使用springboot+WebSocket做聊天室

最近参加实训,负责的相关工作要求实现一个聊天室,因为给的资料里有用WebSocket做聊天室的示例,所以便选择了WebSocket。

原理

WebSocket是一个网络协议,有别于HTTPS协议,它提供一个客户端到服务器的长连接。事实上,就做这个功能而言,我们知道这么多就够了,然后知道它怎么连,就可以实现实时聊天。
但我还是讲讲我的理解,我这只小萌新并不太了解WebSocket的内部工作机制,但还是知道HTTPS和WebSocket的区别的。首先,以前的HTTPS协议是怎么工作的呢,它的服务器是被动的,也就是说我每次要请求什么服务,我就向服务器发出询问,然后等待服务器回应,这必然导致一个延迟。而WebSocket呢,我和你连上了,只要没人提分手,也没出现啥不可抗力的意外(故障,错误),咱就一直连着,你有啥直接和我说,我也一样,也就是说相比HTTPS省去了一次又一次的沟通成本,所以它快,能做实时聊天。

依赖项

我用的是Maven管理项目,要用WebSocket,所以你在正常的配置springboot项目后,在pom.xml里添这个依赖项:`

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

WebSocket使用

先上代码:

import com.gzws.service.MessageService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.websocket.RemoteEndpoint;
import javax.websocket.Session;
import java.io.IOException;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;

public final class WebSocketUtils {
    private static final Logger logger = LoggerFactory.getLogger(WebSocketUtils.class);

    public static MessageService messageService;

    // 存储 websocket session
    public static final Map<String, Session> ONLINE_USER_SESSIONS = new ConcurrentHashMap<>();

    /**
     * @param session 用户 session
     * @param message 发送内容
     */
    public static void sendMessage(Session session, String message) {//发送消息
        if (session == null) {
            return;
        }
        final RemoteEndpoint.Basic basic = session.getBasicRemote();
        if (basic == null) {
            return;
        }
        try {
            basic.sendText(message);
        } catch (IOException e) {
            logger.error("sendMessage IOException ",e);
        }
    }

    public static void sendMessageToId(Long tid,Long sid, String message){//发送消息给特定ID
        Session session=ONLINE_USER_SESSIONS.get(String.valueOf(tid));
        if(session==null){
            messageService.reply(tid,sid,message);
        }else {
            sendMessage(session,message);
            messageService.onLineReply(tid,sid,message);
        }
    }

    public static void sendMessageAll(String message) {//发送消息给全体
        ONLINE_USER_SESSIONS.forEach((sessionId, session) -> sendMessage(session, message));
    }

我这里做成了一个工具类,我们看到里面的方法和成员变量都做成了静态,它本身也不可继承。方法的用处大家都能看出来,这里我们看参数session,很明显WebSocket这里使用session在传消息。我们知道当我们访问一台服务器时,该服务器会为每个用户生成专属的session。
所以我们不妨多想一想:假如我们不在同一个服务器呢?假如对方不在线呢?WebSocket能解决这些问题吗?很显然,不能。它只是一个网络协议,你不能要求它做完所有事。事实上,你得想办法做session共享;还有要在对方不在线时,想办法把消息存起来,然后对方一上线就能看到。
这里得说一下,相信很多人也遇到了在WebSocket里Service注入的问题,咋解决呢,将在WebSocket里的Service设为static,为什么呢:
本质原因:spring管理的都是单例(singleton),和 websocket (多对象)相冲突。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值