博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
java websocket 实现_Java 项目中的 WebSocket 实现
阅读量:7069 次
发布时间:2019-06-28

本文共 6409 字,大约阅读时间需要 21 分钟。

基于 tomcat 的 WebSocket 实现

这种方式需要 tomcat 7.x,JEE7 的支持。

首先创建一个 springboot 项目,在 pom.xml 中导入 websocket 所需要的依赖

org.springframework

spring-websocket

5.0.12.RELEASE

复制代码

然后开启 WebSocket 的自动注册(如果使用的是独立的 servlet 容器,而不是 spring boot 的内置容器,就不需要注入这个,它将由容器自己提供和管理)

package com.example.demowebsocket.demowebsocket.socket;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.web.socket.server.standard.ServerEndpointExporter;

/**

* @author yuanyiwen

* @create 2019-12-03 18:38

* @description

*/

@Configuration

public class WebSocketConfig{

@Bean

public ServerEndpointExporter serverEndpointExporter(){

return new ServerEndpointExporter();

}

}

复制代码

然后就可以创建 WebSocket 服务端啦!主要在于两个部分 :

通过注解 @ServerEndpoint 来声明实例化 WebSocket 服务端

通过注解 @OnOpen、@OnMessage、@OnClose、@OnError 来声明回调函数

package com.example.demowebsocket.demowebsocket.socket;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.stereotype.Component;

import org.springframework.web.socket.TextMessage;

import javax.websocket.*;

import javax.websocket.server.PathParam;

import javax.websocket.server.ServerEndpoint;

import java.io.IOException;

import java.util.Map;

import java.util.concurrent.ConcurrentHashMap;

/**

* @author yuanyiwen

* @create 2019-12-03 18:48

* @description

*/

@ServerEndpoint(value = "/demoSocket/{userId}")

@Component

public class SocketServer{

// 这里使用一个map来维护全部客户端用户

private static Map userMap = new ConcurrentHashMap<>();

// 日志

private Logger logger = LoggerFactory.getLogger(SocketServer.class);

// 用户id

private Long userId;

/**

* 打开连接时触发事件

*/

@OnOpen

public void onOpen(Session session, @PathParam("userId") Long userId) throws IOException{

this.userId = userId;

userMap.put(userId, session);

logger.info("用户" + userId + "已上线");

}

/**

* 收到消息时触发事件

*/

@OnMessage

public void onMessage(String message, Session session) throws IOException, InterruptedException{

logger.info("用户" + userId + "发来的消息为 :" + message);

session.getBasicRemote().sendText("你用户" + userId + "的喜悦,我服某器收到了! ");

// 向全体在线成员推送这条消息

sendMessageFromOneToAll(userId, message);

}

/**

* 关闭连接时触发事件

*/

@OnClose

public void onClose(){

userMap.remove(userId);

logger.info("用户" + userId + "已下线");

}

/**

* 传输消息错误时触发事件

*/

@OnError

public void onError(Throwable error){

logger.error("错误发生");

error.printStackTrace();

}

/**

* 给某个用户发送消息

*/

public void sendMessageToOne(Long userId, String message){

}

/**

* 给所有在线用户发送消息

*/

public void sendMessageToAll(String message){

}

/**

* 由某一用户向全体在线用户推送消息

* @param userId 哪个用户

* @param message 什么消息

*/

public void sendMessageFromOneToAll(Long userId, String message){

userMap.forEach((id, session) -> {

try {

session.getBasicRemote().sendText("用户" + userId + "发消息来啦:" + message);

} catch (IOException e) {

e.printStackTrace();

}

});

}

}

复制代码

最后让我们来检验一下成果!首先用在线 WebSocket 测试开三个用户,然后让用户 2 发一条消息

aa99486a26813d289d5c204baa9bd4e6.png

34ad98eafb4a41d616460c52eb350090.png

f81f52b0a14f282a965657f2f6180634.png

可以看到在用户 2 的消息发送后,每个在线用户都能够收到来自服务器的主动推送 业务完美qwq

基于 Spring 的 WebSocket 实现

这种方式需要 spring4.x 的支持。由于使用了 socketjs,对于不支持 WebSocket 的浏览器可以模拟 WebSocket 的使用。

首先还是创建一个 spring boot 项目,导入依赖

org.springframework.boot

spring-boot-starter-websocket

2.1.3.RELEASE

复制代码

然后新建一个配置类,用于添加服务端点,以接收客户端的连接

package com.example.demowebsocket.demowebsocket.springsocket;

import org.springframework.context.annotation.Bean;

import org.springframework.context.annotation.Configuration;

import org.springframework.web.socket.config.annotation.EnableWebSocket;

import org.springframework.web.socket.config.annotation.WebSocketConfigurer;

import org.springframework.web.socket.config.annotation.WebSocketHandlerRegistry;

/**

* @author yuanyiwen

* @create 2019-12-04 21:40

* @description

*/

@EnableWebSocket

@Configuration

public class WebSocketConfig implements WebSocketConfigurer{

@Override

public void registerWebSocketHandlers(WebSocketHandlerRegistry registry){

// 这里的路径就是访问时的路径

registry.addHandler(myHandler(), "/demoWebsocket").setAllowedOrigins("*");

}

@Bean

public MyWebSocketHandler myHandler(){

return new MyWebSocketHandler();

}

}

复制代码

最后构建服务端,具体的方法基本与上面对应,数据通过 session 进行传输

package com.example.demowebsocket.demowebsocket.springsocket;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.stereotype.Component;

import org.springframework.web.servlet.HandlerInterceptor;

import org.springframework.web.socket.CloseStatus;

import org.springframework.web.socket.TextMessage;

import org.springframework.web.socket.WebSocketSession;

import org.springframework.web.socket.handler.AbstractWebSocketHandler;

import java.io.IOException;

import java.util.Map;

import java.util.concurrent.ConcurrentHashMap;

/**

* @author yuanyiwen

* @create 2019-12-05 20:52

* @description

*/

@Component

public class MyWebSocketHandler extends AbstractWebSocketHandler implements HandlerInterceptor{

// 这里使用一个map来维护全部客户端用户

private static Map userMap = new ConcurrentHashMap<>();

// 日志

private Logger logger = LoggerFactory.getLogger(MyWebSocketHandler.class);

// 用户id

private Long userId;

/**

* 打开连接时触发事件

*/

@Override

public void afterConnectionEstablished(WebSocketSession session) throws Exception{

this.userId = (Long) session.getAttributes().get("userId");

userMap.put(userId, session);

logger.info("用户" + userId + "已上线");

}

/**

* 收到消息时触发事件

*/

@Override

protected void handleTextMessage(WebSocketSession session, TextMessage message) throws Exception{

logger.info("用户" + userId + "发来的消息为 :" + message);

session.sendMessage(new TextMessage("你用户" + userId + "的喜悦,我服某器收到了! "));

// 向全体在线成员推送这条消息

sendMessageFromOneToAll(userId, message);

}

/**

* 关闭连接时触发事件

*/

@Override

public void afterConnectionClosed(WebSocketSession session, CloseStatus closeStatus) throws Exception{

userMap.remove(userId);

logger.info("用户" + userId + "已下线");

}

/**

* 传输消息错误时触发事件

*/

@Override

public void handleTransportError(WebSocketSession session, Throwable exception) throws Exception{

logger.error("错误发生");

exception.printStackTrace();

}

/**

* 给某个用户发送消息

*/

public void sendMessageToUser(Long userId, TextMessage message){

}

/**

* 给所有在线用户发送消息

*/

public void sendMessageToUsers(TextMessage message){

}

/**

* 由某一用户向全体在线用户推送消息

* @param userId 哪个用户

* @param message 什么消息

*/

public void sendMessageFromOneToAll(Long userId, TextMessage message){

userMap.forEach((id, session) -> {

try {

session.sendMessage(new TextMessage("用户" + userId + "发消息来啦:" + message));

} catch (IOException e) {

e.printStackTrace();

}

});

}

}

复制代码

最后检查一下消息发送情况(这里测试的时候是把代码中从session获取userId改成了直接令 userId = 1L)9db425a1d7dcb8fde0a44536eb3bb4b1.png

完成!(。・`ω´・)

转载地址:http://cvqll.baihongyu.com/

你可能感兴趣的文章