大家好,我是程序员大猩猩。
大家都知道,在程序开发期间,websocket接口是某些程序必不可少的一环。但是websocket跟我们平时开发api又不是系统,有时候我们可以使用Spring自带的websocket框架来实现,有时候又觉得使用其他框架更为便利和高效,那么我在此就给大家介绍一下我们常用的几种websocket实现。
1. Springboot内置websocket
内置websocket是我们经常使用,而且是非常广泛使用的。内置包括基本的websocket创建,而且包含sockJS的实现,以下我们只实现基础的websocket的开发。
首先pom.xml导入websocket starter
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-websocket</artifactId>
</dependency>a. 内置websocket服务端
新建一个类,注册服务端点,使spring服务知道我们要创建一个websocket端点服务。
@Configuration
public class WebSocketConfig {
/**
* 注入一个ServerEndpointExporter,该Bean会自动注册使用@ServerEndpoint注解申明的websocket endpoint
*/
@Bean
public ServerEndpointExporter serverEndpointExporter() {
return new ServerEndpointExporter();
}
}
之后,就是实现socket服务了。
@Slf4j
@ServerEndpoint(value = "/ws/....")
@Component
public class WebSocketServer {
// 连接
@OnOpen
public void onOpen(Session session){}
// 关闭
@OnClose
public void onClose(Session session){}
// 发生错误
@OnError
public void onError(Session session, Throwable e) {}
// 收到客户端消息
@OnMessage
public void onMessage(String json, Session session){}
// 广播消息
public <T> void sendAllMessage(T t) throws Exception {
for (WebSocketServer item : webSocketSet) {
log.info("【websocket消息】广播消息:" + t);
synchronized (item.session) {
item.session.getBasicRemote().sendText(JSON.toJSONString(t));
}
}
}
// 点对点消息发送
public <T> void sendOneMessage(String sessionId, T t) throws Exception {
log.info("开始发送消息 " + sessionMap + ": " + sessionId);
Session session = sessionMap.get(sessionId);
if (session != null) {
try {
log.info("【websocket消息】单点消息:" + sessionId);
session.getAsyncRemote().sendText(t.toString());
} catch (Exception e) {
log.info("异常信息:{}", e.toString());
}
} else {
log.info("获取不到session,发送消息失败" + sessionMap);
}
}
}
- b.内置websocket客户端
@Configuration
public class WebSocketClientConfig {
@Bean
public WebSocketConnectionManager webSocketConnectionManager() {
WebSocketHandler handler = new WebSocketHandler() {
@Override
public void afterConnectionEstablished(WebSocketSession session) throws Exception {
// 连接建立后的操作
}
@Override
public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception {
// 处理传输错误的操作
}
@Override
public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception {
// 连接关闭后的操作
}
@Override
public void handleMessage(WebSocketSession session, WebSocketMessage<?> message) throws Exception {
// 处理接收到的消息的操作
}
};
WebSocketConnectionManager manager = new WebSocketConnectionManager(new StandardWebSocketClient(), handler, "ws://localhost:8080/ws/...");
manager.setAutoStartup(true);
return manager;
}
}
2. 使用Java-WebSocket实现
Java-WebSocket 是一个开源的、轻量级的WebSocket客户端和服务器库,它遵循Java API规范(JSR 356)来实现WebSocket协议。这个库允许开发者轻松地在Java应用程序中实现WebSocket通信,而不必关心底层的网络细节。
照旧pom.xml导入组件工具包
<dependency>
<groupId>org.java-websocket</groupId>
<artifactId>Java-WebSocket</artifactId>
<version>1.5.4</version>
</dependency>
a. Java-Websocket服务端
@Slf4j
public class WebSocketServer extends WebSocketServer {
public MyWebSocketServer(int port) {
super(new InetSocketAddress(port));
}
@Override
public void onOpen(WebSocket conn, ClientHandshake handshake) {
log.info("新的连接: " + conn.getRemoteSocketAddress());
}
@Override
public void onClose(WebSocket conn, int code, String reason, boolean remote) {
log.info("连接关闭: " + conn.getRemoteSocketAddress());
}
@Override
public void onMessage(WebSocket conn, String message) {
log.info("收到消息: " + message);
conn.send("你发送的是: " + message);
}
@Override
public void onError(WebSocket conn, Exception ex) {
ex.printStackTrace();
}
public static void main(String[] args) {
// 选择一个端口号
int port = 8887;
MyWebSocketServer server = new MyWebSocketServer(port);
server.start();
log.info("服务器启动在端口: " + port);
}
}
b. Java-Websocket客户端
public class WebSocketClient extends WebSocketClient {
public MyWebSocketClient(URI serverUri) {
super(serverUri);
}
@Override
public void onOpen(ServerHandshake handshakedata) {
System.out.println("连接开启");
send("Hello, Server!"); // 向服务器发送消息
}
@Override
public void onMessage(String message) {
System.out.println("收到消息: " + message);
}
@Override
public void onClose(int code, String reason, boolean remote) {
System.out.println("连接关闭: " + reason);
}
@Override
public void onError(Exception ex) {
ex.printStackTrace();
}
public static void main(String[] args) {
try {
WebSocketClient client = new MyWebSocketClient(new URI("ws://localhost:8887"));
client.connect();
} catch (URISyntaxException e) {
e.printStackTrace();
}
}
}
3. 使用okhttp3实现
okhttp3应该是在android端实现的利器,虽然本人不具备android原生的开发,但是接触okhttp3之后,感觉它应该也是一个非常好的通信框架。而且它也支持socket开发。
但是,我们要知道okhttp3是不提供websocket服务端创建的。
<dependency>
<groupId>com.squareup.okhttp3</groupId>
<artifactId>okhttp</artifactId>
<version>4.9.3</version>
</dependency>
okhttp3客户端实现
public class OkHttpWebSocketClient {
private final OkHttpClient client = new OkHttpClient();
public void start() {
Request request = new Request.Builder()
.url("ws://localhost:8080/ws/...")
.build();
WebSocketListener webSocketListener = new WebSocketListener() {
@Override
public void onOpen(WebSocket webSocket, Response response) {
System.out.println("WebSocket opened");
// 连接打开后发送消息
webSocket.send("Hello, Server!");
}
@Override
public void onMessage(WebSocket webSocket, String text) {
System.out.println("Received message: " + text);
}
@Override
public void onClosing(WebSocket webSocket, int code, String reason) {
System.out.println("WebSocket closing: " + reason);
}
@Override
public void onFailure(WebSocket webSocket, Throwable t, Response response) {
t.printStackTrace();
}
};
client.newWebSocket(request, webSocketListener);
}
public static void main(String[] args) {
new OkHttpWebSocketClient().start();
}
}
4. 使用Jetty时限
Jetty是一个开源的、基于Java的HTTP服务器和Servlet容器。
<dependencies>
<dependency>
<groupId>org.eclipse.jetty.websocket</groupId>
<artifactId>websocket-server</artifactId>
<version>9.4.43.v20210629</version>
</dependency>
</dependencies>
a. Jetty服务端
首先我们需要设置一个websocket的端点
@Slf4j
@WebSocket
public class MyWebSocketEndpoint {
@OnWebSocketConnect
public void onConnect(Session session) throws Exception {
log.info("New connection: " + session.getRemoteAddress().getAddress());
session.getRemote().sendString("Hello, Client!");
}
@OnWebSocketMessage
public void onMessage(Session session, String message) throws Exception {
log.info("Received message: " + message);
session.getRemote().sendString("You said: " + message);
}
@OnWebSocketClose
public void onClose(int statusCode, String reason) {
log.info("Connection closed: " + reason);
}
}
然后我们在启动服务时,启动socket端点
Server server = new Server(8080);
ServletContextHandler context = new ServletContextHandler(ServletContextHandler.SESSIONS);
context.setContextPath("/");
server.setHandler(context);
ServerContainer wscontainer = WebSocketServerContainerInitializer.configureContext(context);
wscontainer.addEndpoint(MyWebSocketEndpoint.class);
server.start();
server.join();
b. Jetty客户端
设置端点
@Slf4j
@WebSocket
public class MyWebSocketClientEndpoint {
@OnWebSocketConnect
public void onConnect(Session session) throws Exception {
log.info("Connected to server");
session.getRemote().sendString("Hello, Server!");
}
@OnWebSocketMessage
public void onMessage(String message) {
log.info("Received message: " + message);
}
@OnWebSocketClose
public void onClose(int statusCode, String reason) {
log.info("Connection closed: " + reason);
}
}
连接服务端
public class JettyWebSocketClient {
public static void main(String[] args) throws Exception {
WebSocketClient client = new WebSocketClient();
try {
client.start();
URI uri = new URI("ws://localhost:8080/myWebSocketEndpoint");
ClientEndpointConfig config = ClientEndpointConfig.Builder.create().build();
Session session = client.connectToServer(new MyWebSocketClientEndpoint(), config, uri);
// 等待连接关闭
session.getCloseFuture().get();
} finally {
client.stop();
}
}
}
以上四种工具类连接方式应该是我们经常用到的,但是不防我们程序员大神开源了很多websocket库,并且很好用。
假如有好用的可以给我留言,大家一起探讨使用,谢谢。