首页 > 其他分享 >175. Spring Boot WebSocket:单聊

175. Spring Boot WebSocket:单聊

时间:2023-06-26 17:35:47浏览次数:48  
标签:socketMsg WebSocket String Spring session 消息 175 nickname public



需求缘起:

       在前面的文章中已经实现了群聊,这里也简单介绍下单聊。这里使用session.getId()中的id作为唯一的消息通道(这里我们称为通讯的频道号), session.getId()是一个递增的数字,从0开始,递增1,2,3… 实际中并不会使用这个id作为标识,这里只是为了讲解方便。

效果展示:

先看下最终实现的效果,如下图:

 

悟空消息:

175. Spring Boot WebSocket:单聊_spring boot实战


 

 

 

师傅消息:

175. Spring Boot WebSocket:单聊_spring boot_02


 

 

 

八戒消息:

175. Spring Boot WebSocket:单聊_spring boot视频_03


 

一、服务端调整

1.1  创建一个Socket消息对象SocketMsg

       这里我们就不能使用简单的文本消息进行消息的发送了,我们使用json进行消息的发送。所以需要先创建一个消息对象,里面包含了消息发送者,消息接受者,消息类型(单聊还是群聊),还是就是消息,如下:

com.kfit.socket.SocketMsg:

package com.kfit.socket;
 
public class SocketMsg {
       private int type;//聊天类型0:群聊,1:单聊.
       private String fromUser;//发送者.
       private String toUser;//接受者.
       private String msg;//消息
       public int getType() {
              return type;
       }
       public void setType(inttype) {
              this.type = type;
       }
       public String getFromUser() {
              return fromUser;
       }
       public void setFromUser(String fromUser) {
              this.fromUser = fromUser;
       }
       public String getToUser() {
              returntoUser;
       }
       public void setToUser(String toUser) {
              this.toUser = toUser;
       }
       public String getMsg() {
              returnmsg;
       }
       public void setMsg(String msg) {
              this.msg = msg;
       }
}




1.2  调整建立连接的方法(MyWebSocket)

       这里主要是要使用一个map对象保存频道号和session之前的关系,之后就可以通过频道号获取session,然后使用session进行消息的发送。

定义一个map对象:

//用来记录sessionId和该session进行绑定 
 private static Map<String,Session> map = new HashMap<String, Session>();





修改连接的方法onOpen:

       在建立连接的时候,就保存频道号(这里使用的是session.getId()作为频道号)和session之间的对应关系:

@OnOpen
    public void onOpen(Session session,@PathParam("nickname") String nickname) {
        this.session = session;
        this.nickname = nickname;
        map.put(session.getId(), session);
       
        webSocketSet.add(this);     //加入set中
        System.out.println("有新连接加入!当前在线人数为" + webSocketSet.size());
        this.session.getAsyncRemote().sendText(this.nickname+"上线了"+"(他的频道号是"+session.getId()+")");
    }




修改消息发送的方法 onMessage:

       从客户端传过来的数据是json数据,所以这里使用jackson进行转换为SocketMsg对象,然后通过socketMsg的type进行判断是单聊还是群聊,进行相应的处理:

@OnMessage
    public void onMessage(String message, Session session,@PathParam("nickname") String nickname) {
        System.out.println("来自客户端的消息:" + message);
 
        ObjectMapper objectMapper = new ObjectMapper();
        SocketMsg socketMsg;
              try {
                     socketMsg = objectMapper.readValue(message, SocketMsg.class);
                     if(socketMsg.getType() == 1){
                            //单聊.需要找到发送者和接受者.
                           
                            socketMsg.setFromUser(session.getId());//发送者.
                            Session fromSession = map.get(socketMsg.getFromUser());
                            Session toSession = map.get(socketMsg.getToUser());
                            //发送给接受者.
                            if(toSession != null){
                                   //发送给发送者.
                                   fromSession.getAsyncRemote().sendText(nickname+":"+socketMsg.getMsg());
                                   toSession.getAsyncRemote().sendText(nickname+":"+socketMsg.getMsg());
                            }else{
                                   //发送给发送者.
                                   fromSession.getAsyncRemote().sendText("系统消息:对方不在线或者您输入的频道号不对");
                            }
                     }else{
                            //群发消息
                      broadcast(nickname,socketMsg);
                     }
              } catch (JsonParseException e) {
                     // TODO Auto-generated catch block
                     e.printStackTrace();
              } catch (JsonMappingException e) {
                     // TODO Auto-generated catch block
                     e.printStackTrace();
              } catch (IOException e) {
                     // TODO Auto-generated catch block
                     e.printStackTrace();
              }
    }





二、客户端调整

2.1 加入频道号输入框

       提供用户输入频道号进行单聊:

消息:<input id="text" type="text" />
频道号<input id="toUser" type="text" />
<button οnclick="send()">发送消息</button>




2.2 修改消息发送方法

       这里使用了js对象进行消息的传递,这里使用JSON.stringify将json对象转换为json字符串,如下代码:

//发送消息
       function send() {
              //获取输入的文本信息进行发送
              var message = document.getElementById('text').value;
              var toUser = document.getElementById('toUser').value;
              var socketMsg = {msg:message,toUser:toUser};
              if(toUser == ''){
                     //群聊.
                     socketMsg.type = 0;
              }else{
                     //单聊.
                     socketMsg.type = 1;
              }
             
              websocket.send(JSON.stringify(socketMsg));
       }




   好了,到这里就可以实现了单聊+群聊的效果。

 

三、新问题的提出

       上面虽然可以实现单聊的方式,但是在具体的实际场景中,想要知道对方的频道号好像不是那么容易的哦,那么这个要怎么解决呢?大家在玩QQ群的时候,应该都用过聊天界面中的右边的群成员吧,对头,就是要实现一个在线群成员列表的功能,这样用户在操作的时候就可以直接通过点击某个在线的用户进行聊天了。博主,你会实现嘛?^_^,博主还暂时没有这个计划,其实看懂了上面的代码之后,要实现在线群成员列表也不是很难的事情了。

 

 

四、源代码

 

       最后奉上源代码。大家可以下载源代码玩玩!

访问地址:https://gitee.com/happyangellxq520/spring-boot 找到spring-boot-websocket-2017,直接下载即可运行。




标签:socketMsg,WebSocket,String,Spring,session,消息,175,nickname,public
From: https://blog.51cto.com/u_11142439/6556181

相关文章

  • 172.Spring Boot WebSocket:编码分析
    前言:       在上一篇文章中讲到了WebSocket的原理,这节中我们先简单的编码分析下,这样有助于在之后的实战编码。说明:(1)编码中使用的SpringBoot版本是: 1.5.8;(2)使用WebSocket有两种方式:第一种方式使用socketJS,第二种方式是使用H5的标准。实例中使用的是第二种方式;(3)最后提......
  • 174. Spring Boot WebSocket:群聊-昵称
     需求缘起:       在上一篇文章已经可以群聊功能了,但是存在一个问题,就是无法显示消息是谁发送了,这样就会导致消息乱七八糟的无法解读。在这版文章中解决昵称显示的问题。效果展示: 悟空消息:   师傅消息:   八戒消息: (1)在连接的时候,让用户输入昵称  ......
  • springboot 跨域设置
      写文章 SpringBoot项目解决跨域的几种方案小满只想睡觉一直快乐!​关注她  在用SpringBoot开发后端服务时,我们一般是提供接口给前端使用,但前端通过浏览器调我们接口时,浏览器会有个同源策略的限制,即协议,域名,端口任一不一样时都会......
  • 深度解析SpringBoot内嵌Web容器
    你好,我是刘牌!前言今天分享一个SpringBoot的内嵌Web容器,在SpringBoot还没有出现时,我们使用Java开发了Web项目,需要将其部署到Tomcat下面,需要配置很多xml文件,SpringBoot出现后,就从繁琐的xml文件中解脱出来了,SpringBoot将Web容器进行了内嵌,我们只需要将项目打成一个jar包,就可以运行......
  • Spring生命周期
    SpringBean的生命周期Spring框架中的组件被称为Bean,每个Bean都有其特定的生命周期。下面是SpringBean的生命周期的主要阶段:实例化:在这个阶段,Spring容器根据Bean定义创建Bean的实例。这可以通过构造函数或工厂方法来实现。属性注入:在实例化完成后,Spring容器将会为Bean的属......
  • Spring IoC有什么好处呢?
      来源   https://www.zhihu.com/question/23277575?utm_id=0   SpringIoC有什么好处呢? 作者:Mingqi链接:https://www.zhihu.com/question/23277575/answer/169698662来源:知乎著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。要了解控......
  • SpringCloud http大文件断点续传上传
    ​ 第一点:Java代码实现文件上传FormFilefile=manform.getFile();StringnewfileName= null;Stringnewpathname= null;StringfileAddre= "/numUp";try{    InputStreamstream=file.getInputStream();// 把文件读入    StringfilePath=request.......
  • spring系列框架有哪些
    springboot包含了springMVC,但后者需要手动配置很多东西才能跑起来,包括繁琐的xml配置,而springboot会自动配置,比如用注解简化了配置(不用配xml),没有手动也会有默认值 SpringBoot就是一个工具,他集成了SpringMVC。Web开发用的实际还是SpringMVC那一套SpringS......
  • SpringMVC http大文件断点续传上传
    ​ 我们平时经常做的是上传文件,上传文件夹与上传文件类似,但也有一些不同之处,这次做了上传文件夹就记录下以备后用。这次项目的需求:支持大文件的上传和续传,要求续传支持所有浏览器,包括ie6,ie7,ie8,ie9,Chrome,Firefox,360安全浏览器,并且刷新浏览器后仍然能够续传,重启浏览器(关闭......
  • 肝了一周总结的SpringBoot常用注解大全,看完就炉火纯青了!
      来源于 https://www.macrozheng.com/mall/reference/springboot_annotation.html  肝了一周总结的SpringBoot常用注解大全,看完就炉火纯青了!   平时使用SpringBoot开发项目,少不了要使用到它的注解。这些注解让我们摆脱了繁琐的传统SpringXML配置,让我们开发项目......