Skip to content

WebSocket

Часть 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

Поделиться в социальных сетях

Опубликовать в Google Plus
Опубликовать в LiveJournal
Опубликовать в Мой Мир
Опубликовать в Одноклассники
Опубликовать в Яндекс

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *