springboot集成websocket

springboot集成websocket

1、引入jar包

		<dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-websocket</artifactId>
        </dependency> 

2、创建config类

@Configuration
public class WebSocketConfig {

    @Bean
    public ServerEndpointExporter serverEndpointExporter() {
        return new ServerEndpointExporter();
    }

}

3、定义websocket服务

/**
 * @ServerEndpoint 注解是一个类层次的注解,它的功能主要是将目前的类定义成一个websocket服务器端,注解的值将被用于监听用户连接的终端访问URL地址,
 * 客户端可以通过这个URL来连接到WebSocket服务器端,可以把当前类变成websocket服务类
 */
@Slf4j
@ServerEndpoint("/websocket/{userId}")
@Component
public class WebSocketService {

    //因为websocket无法注入其他的bean,则要手动注入,需要在此处定义bean,然后下边进行赋值
    private static WarningService warningService;

    //手动注入一个bean
    @Autowired
    public void setChatService(WarningService warningService) {
        WebSocketService.warningService = warningService;
    }

    //用来存放所有的在线用户的session
    private static final ConcurrentHashMap<String, Session> webSocketMap = new ConcurrentHashMap<>();

    /**
     * 客户端建立连接调用方法
     *
     * @param userId  用户id
     * @param session session
     */
    @OnOpen
    public void onOpen(@PathParam(value = "userId") String userId, Session session) {
        webSocketMap.put(userId, session);
        log.info("【websocket消息】有新的连接, 总数: " + webSocketMap.size() + " 用户id: " + userId);
        //用户建立连接 可以执行你的逻辑,把逻辑写在warningService类里的onOpenByAlert方法
        warningService.onOpenByAlert(userId);
    }

    /**
     * 客户端断开连接调用方法
     *
     * @param userId  用户id
     * @param session session
     */
    @OnClose
    public void onClose(@PathParam(value = "userId") String userId, Session session) {
        webSocketMap.remove(userId);
        log.info("【websocket消息】连接断开, 总数: " + webSocketMap.size() + " 用户id已离开: " + userId);
    }

    /**
     * 收到客户端发来的消息
     *
     * @param message 消息
     */
    @OnMessage
    public void onMessage(@PathParam(value = "userId") String userId, String message) {
        log.info("【websocket消息】收到客户端用户 " + userId + " 发来的消息" + message);
        //心跳确认连接,由于nginx代理,那边配置了连接失效时间,这边每隔一段时间,互相发送一个消息来保证websocket始终连接。当收到ping消息的时候,向客户端回复一个received
        if ("ping".equals(message)) {
            sendMessage(userId, "received");
        } else {
            //收到用户的消息,用来处理自己的逻辑
            warningService.onMessageAlert(userId, message);
        }
    }

    /**
     * 发生异常
     *
     * @param session session
     * @param error   error
     */
    @OnError
    public void onError(Session session, Throwable error) {
        log.info("【websocket消息】收到客户端用户发生错误");
        error.printStackTrace();
    }

    /**
     * 给指定用户发送消息
     *
     * @param userId  用户id
     * @param message 消息
     */
    public void sendMessage(String userId, String message) {
        try {
            if (webSocketMap.get(userId) != null) {
                sendMessage(webSocketMap.get(userId), message);
                log.info("【websocket消息】向客户端用户 " + userId + "发送消息成功-" + message);
            } else {
                log.info("【websocket消息】向客户端用户 " + userId + "发送消息失败,用户已离线");
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 发送消息
     *
     * @param session session
     */
    public void sendMessage(Session session, String message) throws IOException {
        //同步发送
        //session.getBasicRemote().sendText(message);
        //异步发送
        session.getAsyncRemote().sendText(message);
    }

}

4、直接调用发送消息

new WebSocketService().sendMessage(userId, "你好!123");

5、客户端连接

请求地址:ws://192.168.0.141:8089/websocket/123

6、部署到服务器

如果配置了nginx会链接失败,
在nginx配置文件 location 里加入下边代码,在重启nginx即可
# 增加Upgrade协议头和Connection协议头,使http连接升级到websocket连接
proxy_set_header Upgrade $http_upgrade;
proxy_set_header Connection "upgrade";
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值