Часть 1. Серверная часть
Структура серверного проекта
web-socket-server ├──src │ └─com │ └─dev │ └─blogs │ └─web_socket_server │ ├─WebSocketServer.java │ ├─SocketHandler.java │ └─MySocket.java └──pom.xml
WebSocketServer.java
package com.dev.blogs.web_socket_server; import org.eclipse.jetty.server.Handler; import org.eclipse.jetty.server.Server; import org.eclipse.jetty.server.ServerConnector; import org.eclipse.jetty.server.handler.HandlerList; import org.eclipse.jetty.server.handler.ResourceHandler; public class WebSocketServer { public static void main(String[] args) { Server server = new Server(); ServerConnector connector = new ServerConnector(server); connector.setPort(8080); server.addConnector(connector); // add first handler ResourceHandler resource_handler = new ResourceHandler(); resource_handler.setDirectoriesListed(true); resource_handler.setWelcomeFiles(new String[]{ "index.html" }); resource_handler.setResourceBase("."); HandlerList handlers = new HandlerList(); // first element is webSocket handler, second element is first handler handlers.setHandlers(new Handler[] {new SocketHandler()}); server.setHandler(handlers); try { server.start(); server.join(); } catch (Throwable t) { t.printStackTrace(System.err); } } }
SocketHandler.java
package com.dev.blogs.web_socket_server; import org.eclipse.jetty.websocket.server.WebSocketHandler; import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory; public class SocketHandler extends WebSocketHandler { @Override public void configure(WebSocketServletFactory factory) { factory.register(MySocket.class); } }
MySocket.java
package com.dev.blogs.web_socket_server; import java.io.IOException; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose; import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect; import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage; import org.eclipse.jetty.websocket.api.annotations.WebSocket; @WebSocket public class MySocket { private Session session; @OnWebSocketConnect public void onConnect(Session session) { System.out.println("Connect: " + session.getRemoteAddress().getAddress()); try { this.session = session; session.getRemote().sendString("Got your connect message"); } catch (IOException e) { e.printStackTrace(); } } @OnWebSocketMessage public void onText(String message) { System.out.println("text: " + message); try { this.session.getRemote().sendString(message); } catch (Exception e) { e.printStackTrace(); } } @OnWebSocketClose public void onClose(int statusCode, String reason) { System.out.println("Close: statusCode=" + statusCode + ", reason=" + reason); } }
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.dev.blogs</groupId> <artifactId>web-socket-server</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>web-socket-server</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <!-- Server, ServerConnector --> <dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-server</artifactId> <version>9.1.3.v20140225</version> </dependency> <!-- WebSocketHandler, WebSocketServletFactory --> <dependency> <groupId>org.eclipse.jetty.websocket</groupId> <artifactId>websocket-server</artifactId> <version>9.1.3.v20140225</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>exec-maven-plugin</artifactId> <version>1.3.2</version> </plugin> </plugins> </build> </project>
Запуск сервера
mvn exec:java -Dexec.mainClass="com.dev.blogs.web_socket_server.WebSocketServer" [INFO] Scanning for projects... [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building web-socket-server 0.0.1-SNAPSHOT [INFO] ------------------------------------------------------------------------ [INFO] [INFO] --- exec-maven-plugin:1.3.2:java (default-cli) @ web-socket-server --- WARNING Warning: killAfter is now deprecated. Do you need it ? Please comment on MEXEC-6. 2015-07-21 17:14:32.547:INFO::com.dev.blogs.web_socket_server.WebSocketServer.ma in(): Logging initialized @2673ms 2015-07-21 17:14:32.674:INFO:oejs.Server:com.dev.blogs.web_socket_server.WebSock etServer.main(): jetty-9.1.3.v20140225 2015-07-21 17:14:32.813:INFO:oejs.ServerConnector:com.dev.blogs.web_socket_serve r.WebSocketServer.main(): Started ServerConnector@31384986{HTTP/1.1}{0.0.0.0:808 0} 2015-07-21 17:14:32.813:INFO:oejs.Server:com.dev.blogs.web_socket_server.WebSock etServer.main(): Started @2879ms
Часть 2. Клиентская часть
Структура клиентского проекта
webSocket-client ├──src │ └─com │ └─dev │ └─blogs │ └─webSocket_client │ ├─Client.java │ └─WebSocketHandler.java └──pom.xml
Client.java
package com.dev.blogs.webSocket_client; import java.net.URI; import java.util.concurrent.TimeUnit; import org.eclipse.jetty.websocket.client.ClientUpgradeRequest; import org.eclipse.jetty.websocket.client.WebSocketClient; public class Client { public static void main(String [] args) { String destUri = "ws://localhost:8080"; WebSocketClient client = new WebSocketClient(); WebSocketHandler socket = new WebSocketHandler(); try { client.start(); URI echoUri = new URI(destUri); ClientUpgradeRequest request = new ClientUpgradeRequest(); client.connect(socket, echoUri, request); System.out.printf("Connecting to : %s%n", echoUri); socket.awaitClose(5, TimeUnit.SECONDS); } catch (Throwable t) { t.printStackTrace(); } finally { try { client.stop(); } catch (Exception e) { e.printStackTrace(); } } } }
WebSocketHandler.java
package com.dev.blogs.webSocket_client; import java.util.concurrent.CountDownLatch; import java.util.concurrent.Future; import java.util.concurrent.TimeUnit; import org.eclipse.jetty.websocket.api.Session; import org.eclipse.jetty.websocket.api.StatusCode; import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose; import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect; import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage; import org.eclipse.jetty.websocket.api.annotations.WebSocket; /** * Basic Echo Client Socket */ @WebSocket(maxTextMessageSize = 64 * 1024) public class WebSocketHandler { private final CountDownLatch closeLatch; @SuppressWarnings("unused") private Session session; public WebSocketHandler() { this.closeLatch = new CountDownLatch(1); } public boolean awaitClose(int duration, TimeUnit unit) throws InterruptedException { return this.closeLatch.await(duration, unit); } @OnWebSocketClose public void onClose(int statusCode, String reason) { System.out.printf("Connection closed: %d - %s%n", statusCode, reason); this.session = null; this.closeLatch.countDown(); } @OnWebSocketConnect public void onConnect(Session session) { System.out.printf("Got connect: %s%n", session); this.session = session; try { Future<Void> fut; fut = session.getRemote().sendStringByFuture("Hello"); fut.get(2, TimeUnit.SECONDS); fut = session.getRemote().sendStringByFuture("Thanks for the conversation."); fut.get(2, TimeUnit.SECONDS); session.close(StatusCode.NORMAL, "I'm done"); } catch (Throwable t) { t.printStackTrace(); } } @OnWebSocketMessage public void onMessage(String msg) { System.out.printf("Got msg: %s%n", msg); } }
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.dev.blogs</groupId> <artifactId>webSocket-client</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>webSocket-client</name> <url>http://maven.apache.org</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> </properties> <dependencies> <dependency> <groupId>org.eclipse.jetty.websocket</groupId> <artifactId>websocket-client</artifactId> <version>9.2.12.v20150709</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> </dependencies> </project>
Запуск клиента
Клиент
Отправленные и полученные данные подсвечены красным:
mvn exec:java -Dexec.mainClass="com.dev.blogs.webSocket_client.Client" [INFO] Scanning for projects... [INFO] [INFO] ------------------------------------------------------------------------ [INFO] Building webSocket-client 0.0.1-SNAPSHOT [INFO] ------------------------------------------------------------------------ [INFO] [INFO] --- exec-maven-plugin:1.3.2:java (default-cli) @ webSocket-client --- WARNING Warning: killAfter is now deprecated. Do you need it ? Please comment on MEXEC-6. 2015-07-21 17:36:18.548:INFO::com.dev.blogs.webSocket_client.Client.main(): Logg ing initialized @2733ms Connecting to : ws://localhost:8080 Got connect: WebSocketSession[websocket=JettyAnnotatedEventDriver[com.dev.blogs. webSocket_client.WebSocketHandler@df70c78],behavior=CLIENT,connection=WebSocketC lientConnection@731e9137{IDLE}{f=Flusher[queueSize=0,aggregateSize=0,failure=nul l],g=Generator[CLIENT,validating],p=Parser@457c96c[ExtensionStack,s=START,c=0,le n=0,f=null,p=WebSocketPolicy@23a84fca[behavior=CLIENT,maxTextMessageSize=65536,m axTextMessageBufferSize=32768,maxBinaryMessageSize=65536,maxBinaryMessageBufferS ize=32768,asyncWriteTimeout=60000,idleTimeout=300000,inputBufferSize=4096]]},rem ote=WebSocketRemoteEndpoint@3b758f4d[batching=true],incoming=JettyAnnotatedEvent Driver[com.dev.blogs.webSocket_client.WebSocketHandler@df70c78],outgoing=Extensi onStack[queueSize=0,extensions=[],incoming=org.eclipse.jetty.websocket.common.We bSocketSession,outgoing=org.eclipse.jetty.websocket.client.io.WebSocketClientCon nection]]Got msg: Got your connect message Got msg: Hello Got msg: Thanks for the conversation. Connection closed: 1000 - I'm done [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 1.228 s [INFO] Finished at: 2015-07-21T17:36:18+03:00 [INFO] Final Memory: 8M/123M [INFO] ------------------------------------------------------------------------
Сервер
Connect: /127.0.0.1 text: Hello text: Thanks for the conversation. Close: statusCode=1000, reason=I'm done
Часть 3. Клиентская часть (редакция 2)
Структура клиентского проекта (редакция 2)
webSocket-client-edit2 ├──src │ └─com │ └─dev │ └─blogs │ └─webSocket_client_edit2 │ ├─ClientEdit2.java │ └─WebsocketClientEndpoint.java └──pom.xml
ClientEdit2.java
package com.dev.blogs.webSocket_client_edit2; import java.net.URI; import java.net.URISyntaxException; public class ClientEdit2 { public static void main(String[] args) throws Exception { try { URI uri = new URI("ws://localhost:8080"); // open websocket WebsocketClientEndpoint clientEndPoint = new WebsocketClientEndpoint(uri); // add listener clientEndPoint.addMessageHandler(new WebsocketClientEndpoint.MessageHandler() { public void handleMessage(String message) { System.out.println(message); } }); // send message to websocket clientEndPoint.sendMessage("test message"); // wait 1 seconds for messages from websocket Thread.sleep(1000); } catch (InterruptedException ex) { System.err.println("InterruptedException exception: " + ex.getMessage()); } catch (URISyntaxException ex) { System.err.println("URISyntaxException exception: " + ex.getMessage()); } } }
WebsocketClientEndpoint.java
package com.dev.blogs.webSocket_client_edit2; import java.net.URI; import javax.websocket.ClientEndpoint; import javax.websocket.CloseReason; import javax.websocket.ContainerProvider; import javax.websocket.OnClose; import javax.websocket.OnMessage; import javax.websocket.OnOpen; import javax.websocket.Session; import javax.websocket.WebSocketContainer; @ClientEndpoint public class WebsocketClientEndpoint { Session userSession = null; private MessageHandler messageHandler; public WebsocketClientEndpoint(URI endpointURI) { try { WebSocketContainer container = ContainerProvider.getWebSocketContainer(); container.connectToServer(this, endpointURI); } catch (Exception e) { throw new RuntimeException(e); } } /** * Callback hook for Connection open events. * * @param userSession * the userSession which is opened. */ @OnOpen public void onOpen(Session userSession) { System.out.println("opening websocket"); this.userSession = userSession; } /** * Callback hook for Connection close events. * * @param userSession * the userSession which is getting closed. * @param reason * the reason for connection close */ @OnClose public void onClose(Session userSession, CloseReason reason) { System.out.println("closing websocket"); this.userSession = null; } /** * Callback hook for Message Events. This method will be invoked when a * client send a message. * * @param message * The text message */ @OnMessage public void onMessage(String message) { if (this.messageHandler != null) { this.messageHandler.handleMessage(message); } } /** * register message handler * * @param message */ public void addMessageHandler(MessageHandler msgHandler) { this.messageHandler = msgHandler; } /** * Send a message. * * @param user * @param message */ public void sendMessage(String message) { this.userSession.getAsyncRemote().sendText(message); } /** * Message handler. * * @author Jiji_Sasidharan */ public static interface MessageHandler { public void handleMessage(String message); } }
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.dev.blogs</groupId> <artifactId>webSocket-client-edit2</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>webSocket-client-edit2</name> <url>http://maven.apache.org</url> <properties> <jetty.version>9.2.11.v20150529</jetty.version> </properties> <build> <plugins> <plugin> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-maven-plugin</artifactId> <version>${jetty.version}</version> </plugin> </plugins> </build> <dependencies> <!--JSR-356 Websocket client side depencency --> <dependency> <groupId>org.eclipse.jetty.websocket</groupId> <artifactId>javax-websocket-client-impl</artifactId> <version>${jetty.version}</version> </dependency> </dependencies> </project>
Запуск клиента
Запускается клиент точно так же:
mvn exec:java -Dexec.mainClass="com.dev.blogs.webSocket_client_edit2.ClientEdit2"
Часть 4. Клиентская часть (редакция 3)
Структура клиентского проекта (редакция 3)
webSocket-client-edit3 ├──src │ └─com │ └─dev │ └─blogs │ └─webSocket_client_edit3 │ └─ClientEdit3.java └──pom.xml
ClientEdit3
package com.dev.blogs.webSocket_client_edit3; import java.net.URI; import java.util.concurrent.TimeUnit; import org.eclipse.jetty.websocket.WebSocket; import org.eclipse.jetty.websocket.WebSocketClient; import org.eclipse.jetty.websocket.WebSocketClientFactory; public class ClientEdit3 { public static void main(String[] args) throws Exception { WebSocketClientFactory factory = new WebSocketClientFactory(); factory.start(); WebSocketClient client = factory.newWebSocketClient(); // Configure the client WebSocket.Connection connection = client.open(new URI("ws://localhost:8080"), new WebSocket.OnTextMessage() { public void onOpen(Connection connection) { System.out.println("OnOpen"); } public void onClose(int closeCode, String message) { System.out.println("OnClose"); } public void onMessage(String data) { System.out.println("OnMessage: " + data); } }).get(5, TimeUnit.SECONDS); connection.disconnect(); } }
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>com.dev.blogs</groupId> <artifactId>webSocket-client-edit3</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>webSocket-client-edit3</name> <url>http://maven.apache.org</url> <properties> <jetty.version>9.2.11.v20150529</jetty.version> </properties> <dependencies> <dependency> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-websocket</artifactId> <version>8.0.0.v20110901</version> </dependency> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.eclipse.jetty</groupId> <artifactId>jetty-maven-plugin</artifactId> <version>${jetty.version}</version> </plugin> </plugins> </build> </project>
Запуск клиента
mvn exec:java -Dexec.mainClass="com.dev.blogs.webSocket_client_edit3.ClientEdit3"
Ссылки
Jetty WebSocket Client API
WebSocket.org
http://stackoverflow.com/questions/26452903/javax-websocket-client-simple-example
http://stackoverflow.com/questions/27293982/howto-add-request-header-to-tyrus-annotation-based-client