接上文,“websocket协议简析”。分享一下基于jetty9实现java版的webcoket服务端和客户端demo。
没有理论,话不多说,代码奉上。
准备工作:
新建maven工程,pom文件引入:
org.eclipse.jetty.websocket
websocket-client
9.4.6.v20170531
org.eclipse.jetty.websocket
websocket-server
9.4.6.v20170531
org.eclipse.jetty.websocket
websocket-api
9.4.6.v20170531
服务端实现:
服务端启动类:
package jasonleewebsocket.websocket.server;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.websocket.server.WebSocketHandler;
import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory;
public class WebSocketServerTest{
public static void main(String args[])
{
Server server = new Server(7778);
WebSocketHandler wsHandler = new WebSocketHandler(){
@Override
public void configure(WebSocketServletFactory factory)
{
//注册自定义事件监听器
factory.register(MyEchoSocket.class);
}
};
ContextHandler context = new ContextHandler();
context.setContextPath("/echo");
context.setHandler(wsHandler);
server.setHandler(wsHandler);
try
{
server.start();
server.join();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
自定义监听类:
package jasonleewebsocket.websocket.server;
import java.io.IOException;
import java.nio.ByteBuffer;
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
import org.eclipse.jetty.websocket.api.Session;
import org.eclipse.jetty.websocket.api.WebSocketListener;
import org.eclipse.jetty.websocket.api.WriteCallback;
public class MyEchoSocket implements WebSocketListener{
//维持session
private static final Set< Session > sessions =
Collections.synchronizedSet( new HashSet< Session >() );
private Session session;
//连接关闭,移除session列表
public void onWebSocketClose(int statusCode, String reason) {
System.out.println(reason);
sessions.remove(this.session);
this.session = null;
}
//建立连接后保存session
public void onWebSocketConnect(Session session) {
this.session = session;
System.out.println(session.isOpen());
sessions.add(session);
}
//错误处理
public void onWebSocketError(Throwable cause) {
System.out.println(cause.getMessage());
}
//接收字符串类型消息,并通知所有客户端
public void onWebSocketBinary(byte[] payload, int offset, int len) {
System.out.println("WebSocketBinary:"+new String(payload));
for(final Session session : sessions){
session.getRemote().sendBytes(ByteBuffer.wrap(payload), new WriteCallback() {
//回调处理发送是否成功
public void writeSuccess() {
System.out.println("success");
}
public void writeFailed(Throwable x) {
System.out.println("senderror:"+x.getMessage());
}
});
}
}
//接收字符串类型消息,并转发给所有客户端
public void onWebSocketText(String message) {
System.out.println("text message:"+message);
try {
for(final Session session : sessions){
session.getRemote().sendString("server to convert text:"+message);
}
} catch (IOException e) {
e.printStackTrace();
}
}
}
客户端实现:
客户端启动类:
package jasonleewebsocket.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 SimpleEchoClient
{
public static void main(String[] args)
{
String destUri = "ws://localhost:7778/echo";
if (args.length > 0)
{
destUri = args[0];
}
WebSocketClient client = new WebSocketClient();
SimpleEchoSocket socket = new SimpleEchoSocket();
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);
// wait for closed socket connection.
socket.awaitClose(500,TimeUnit.SECONDS);
}
catch (Throwable t)
{
t.printStackTrace();
}
finally
{
try
{
client.stop();
}
catch (Exception e)
{
e.printStackTrace();
}
}
}
}
客户端监听类:
package jasonleewebsocket.websocket.client;
import java.nio.ByteBuffer;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import org.eclipse.jetty.websocket.api.Session;
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 SimpleEchoSocket {
private final CountDownLatch closeLatch;
public SimpleEchoSocket() {
this.closeLatch = new CountDownLatch(1);
}
public boolean awaitClose(int duration, TimeUnit unit) throws InterruptedException {
return this.closeLatch.await(duration, unit);
}
@OnWebSocketMessage
public void onMessage(String msg) {
System.out.printf("Got msg: %s%n", msg);
}
@OnWebSocketMessage
public void onMessage(byte[] buffer, int offset, int length) {
System.out.printf("Got msg: %s%n", new String(buffer));
}
@OnWebSocketConnect
public void onConnect(Session session) {
System.out.printf("Got connect: %s%n", session);
try {
session.getRemote().sendBytes(ByteBuffer.wrap("test byte".getBytes()));
session.getRemote().sendString("456");
} catch (Throwable t) {
t.printStackTrace();
}
}
}