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 {
Future connectionFuture = 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();
Вот так все просто.