Java Client WebSockets
Собственно решил сделать небольшую заметку про websocketы,а точнее реализация их клиентов на Java,серверной части тут не будет(она особо нам и не нужна для наших целей),
зато будут 2 реализации,кому какая больше нравится.
Итак,коротко что такое WebSocket:
WebSocket — протокол полнодуплексной связи поверх TCP-соединения, предназначенный для обмена сообщениями между браузером и веб-сервером в режиме реального времени.
Можно даже не до конца понимать определение из википедии,чтобы понять насколько широкие горизонты в разработке и тестировании открывает эта технология.
Сейчас напишем пару клиентских программ использующих вебсокет для соединения с сервером.
1й варинт.
Добавляем в pom.xml
Добавляем в pom.xml
javax.websocket javax.websocket-client-api 1.0 org.glassfish.tyrus tyrus-client 1.1 org.glassfish.tyrus tyrus-container-grizzly 1.1
И код самого клиента
@ClientEndpoint(configurator = WebSocketClientEndpoint.Configurator.class) public class WebSocketClientEndpoint { private Logger logger = Logger.getLogger(WebSocketClientEndpoint.class); Session userSession = null; private MessageHandler messageHandler; public static class Configurator extends javax.websocket.ClientEndpointConfig.Configurator { static String cookiesConf; public static void addCookie(String cookies) { cookiesConf = cookies; } @Override public void beforeRequest(Map> headers) { headers.put("Cookie", Collections.singletonList(cookiesConf)); super.beforeRequest(headers); } } public WebSocketClientEndpoint(String host, String port) { try { WebSocketContainer container = ContainerProvider.getWebSocketContainer(); container.connectToServer(this, URI.create("ws://" + host + ":" + port)); } catch (Exception e) { throw new RuntimeException(e); } } @OnError public void onError(Throwable t) { t.printStackTrace(); } /** * Callback hook for Connection open events. * * @param userSession the userSession which is opened. */ @OnOpen public void onOpen(Session userSession) { logger.info("Opening WS"); 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) { logger.info("Closing WS"); 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 */ public WebSocketClientEndpoint addMessageHandler(MessageHandler msgHandler) { this.messageHandler = msgHandler; return this; } /** * Send a message. * * @param message */ public WebSocketClientEndpoint sendMessage(String message) { this.userSession.getAsyncRemote().sendText(message); if (this.messageHandler != null) this.messageHandler.handleMessage(message); return this; } public interface MessageHandler { void handleMessage(String message); } }
И пользуемся им как то так:
WebsocketClientEndpoint clientEndPoint = new WebsocketClientEndpoint(new URI("ws://test.dev:8080")); // add listener clientEndPoint.addMessageHandler(message -> System.out.println(message)); // send message to websocket clientEndPoint.sendMessage("{'event':'Hello world!'}");
Вроде удобно,просто и быстро.Но мне понадобилась поддержка cookie и в данной реализации это создает определенные сложности(вроде статического класса конфигуратора),так что я использовал 2й вариант на jetty.
Добавляем в pom.xml
org.eclipse.jetty.aggregate jetty-all-server 8.1.16.v20140903 org.eclipse.jetty.websocket websocket-client 9.2.10.v20150310
И код самого клиента:
public class ClientWebSocket { private Logger logger = Logger.getLogger(ClientWebSocket.class); private WebSocket.Connection connection; private WebSocketClient client; private WebSocketClientFactory factory; ClientWebSocket() { factory = new WebSocketClientFactory(); try { factory.start(); } catch (Exception e) { logger.info("Factory start problem"); } client = new WebSocketClient(factory); } public ClientWebSocket open(String uri) { try { FutureconnectionFuture = client.open(URI.create(uri), new WebSocket.OnTextMessage() { @Override public void onMessage(String s) { logger.info(s); } @Override public void onOpen(Connection connection) { logger.info("Opening WS"); } @Override public void onClose(int i, String s) { logger.info("Closing WS"); } }); try { this.connection = connectionFuture.get(); } catch (InterruptedException | ExecutionException e) { logger.info("Cant get connection ws"); } } catch (IOException e) { logger.info("IO exception with open ws"); } return this; } public ClientWebSocket addCookies(String name, String value) { client.getCookies().put(name, value); return this; } public ClientWebSocket sendMessage(String mess) { try { connection.sendMessage(mess); } catch (Exception e) { logger.info("Plz open the connection"); } return this; } public ClientWebSocket closeConnection() { try { connection.close(); factory.stop(); } catch (Exception e) { logger.info("Close connection error"); } return this; } }
И используем его как то так:
String uri = "ws://test.dev:8080"; ClientWebSocket client = new ClientWebSocket(); client.addCookies("_user_id", "111111").open(uri).sendMessage("{'event':'Hello world!'}").closeConnection();
Вот так все просто.