socket.io是一个不错的websocket项目,github上有它的java实现:netty-socketio 及 示例项目 netty-socketio-demo,基本上看看demo示例项目就能很快上手了,但是demo中的示例代码场景为js做客户端,如果需要在java中连接websocket server,可以参考下面的示例:
一、服务端代码
package com.corundumstudio.socketio.demo.server; import com.corundumstudio.socketio.AckRequest; import com.corundumstudio.socketio.Configuration; import com.corundumstudio.socketio.SocketIOClient; import com.corundumstudio.socketio.SocketIOServer; import com.corundumstudio.socketio.listener.ConnectListener; import com.corundumstudio.socketio.listener.DataListener; import io.socket.client.Socket; /** * Created by yangjunming on 2017/1/13. */ public class DemoSocketServer { public static void main(String[] args) throws InterruptedException { Configuration config = new Configuration(); config.setHostname("localhost"); config.setPort(9092); final SocketIOServer server = new SocketIOServer(config); server.addConnectListener(new ConnectListener() { @Override public void onConnect(SocketIOClient client) { String token = client.getHandshakeData().getUrlParams().get("token").get(0); if (!token.equals("87df42a424c48313ef6063e6a5c63297")) { client.disconnect();//校验token示例 } System.out.println("sessionId:" + client.getSessionId() + ",token:" + token); } }); server.addEventListener(Socket.EVENT_MESSAGE, String.class, new DataListener<String>() { @Override public void onData(SocketIOClient client, String data, AckRequest ackSender) throws Exception { System.out.println("client data:" + data); server.getBroadcastOperations().sendEvent(Socket.EVENT_MESSAGE, "hi"); } }); server.start(); Thread.sleep(Integer.MAX_VALUE); server.stop(); } }
服务端的主要工作,就是添加各种事件的监听,然后在监听处理中,做相应的处理即可。
二、客户端代码
java连接netty-socketio,还要借助另一个开源项目:socket.io-client-java
package com.corundumstudio.socketio.demo.client; import io.socket.client.IO; import io.socket.client.Socket; import io.socket.emitter.Emitter; import java.net.URISyntaxException; /** * Created by yangjunming on 2017/1/13. */ public class DemoSocketClient { public static void main(String[] args) throws URISyntaxException, InterruptedException { IO.Options options = new IO.Options(); options.transports = new String[]{"websocket"}; options.reconnectionAttempts = 2; options.reconnectionDelay = 1000;//失败重连的时间间隔 options.timeout = 500;//连接超时时间(ms) // final Socket socket = IO.socket("http://localhost:9092/?token=123456", options);//错误的token值连接示例 final Socket socket = IO.socket("http://localhost:9092/?token=87df42a424c48313ef6063e6a5c63297", options); socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() { @Override public void call(Object... args) { socket.send("hello"); } }); socket.on(Socket.EVENT_DISCONNECT, new Emitter.Listener() { @Override public void call(Object... args) { System.out.println("连接关闭"); } }); socket.on(Socket.EVENT_MESSAGE, new Emitter.Listener() { @Override public void call(Object... args) { System.out.println("sessionId:" + socket.id()); for (Object obj : args) { System.out.println(obj); } System.out.println("收到服务器应答,将要断开连接..."); socket.disconnect(); } }); socket.connect(); } }
客户端类似,也是加一些事件监听,然后做相应处理即可。
上面的例子,演示了client向server连接时,如何做基本的连接认证(基于token),以及基本的消息收发。
运行效果:
服务端输出
sessionId:f52e9fa3-6216-4742-87de-3228a74469f9,token:87df42a424c48313ef6063e6a5c63297
client data:hello
客户端输出
sessionId:f52e9fa3-6216-4742-87de-3228a74469f9
hi
收到服务器应答,将要断开连接...
连接关闭
注:框架已经自带了一些预设的事件,见下面的代码片段
/** * Called on a successful connection. */ public static final String EVENT_OPEN = "open"; /** * Called on a disconnection. */ public static final String EVENT_CLOSE = "close"; public static final String EVENT_PACKET = "packet"; public static final String EVENT_ERROR = "error"; /** * Called on a connection error. */ public static final String EVENT_CONNECT_ERROR = "connect_error"; /** * Called on a connection timeout. */ public static final String EVENT_CONNECT_TIMEOUT = "connect_timeout"; /** * Called on a successful reconnection. */ public static final String EVENT_RECONNECT = "reconnect"; /** * Called on a reconnection attempt error. */ public static final String EVENT_RECONNECT_ERROR = "reconnect_error"; public static final String EVENT_RECONNECT_FAILED = "reconnect_failed"; public static final String EVENT_RECONNECT_ATTEMPT = "reconnect_attempt"; public static final String EVENT_RECONNECTING = "reconnecting"; public static final String EVENT_PING = "ping"; public static final String EVENT_PONG = "pong";
如果不够的话,可以自行扩展,无非就是一些字符串常量。
原文:http://www.cnblogs.com/yjmyzz/p/netty-socketio-demo.html