阅读 134

使用WebSocket实现一个简单的页面聊天

上一篇对WebSocket进行了介绍,这次使用WebSocket来实现一个简单的页面聊天的功能。

准备

需要注意:
tomcat6是不支持WebSocket的,从tomcat7才开始支持。
普通的JaveEE、JSPServlet项目也是不支持WebSocket的,需要拷贝额外的jar包

相关依赖

这里使用开发工具创建SpringBoot项目时可以直接将依赖加入至项目中

前段需要用到的JS

代码

后台Configuration

在这里对WebSocket进行基本的配置

@Configuration
@EnableWebSocketMessageBroker //开启信息代理
public class WebSocketConfig implements WebSocketMessageBrokerConfigurer {
    /**
     * 配置连接点信息
     * @param registry
     */
    @Override
    public void  registerStompEndpoints(StompEndpointRegistry registry){
        //连接点,这里的withSockJS() 是前段库
        registry.addEndpoint("/ws/ep").withSockJS();    
    }

    /**
     * 配置消息队列(代理)
     * @param registry
     */
    @Override
    public void configureMessageBroker(MessageBrokerRegistry registry) {
        //启动代理,这里可以配置多个,/queue 代表的是点对点的消息
        registry.enableSimpleBroker("/queue");  
    }
}
复制代码

后台Controller

@Controller //注意这里使用的是Controller注解,而不是RestController
public class WsController {
    //只要引入了WebSocket依赖,就会自动注册这个Bean
    @Autowired
    SimpMessagingTemplate simpMessagingTemplate;   

    /**
     * 这个方法用来接收客户端发来送来的消息,参数是消息本身
     * 通信协议可以自定义,即参数的格式可以自定义
     * 可以接受JSON参数,且不需要添加注解
     * @param msg
     * @param principal  保存了用户信息
     */
    @MessageMapping("/ws/chat") //消息映射
    public void receiveMessage(String msg,Principal principal){
        //从前段发送过来的字符串通过 ; 号拆分出最后一节字符串(需要接受信息的客户端)
        String[] split = msg.split(";");
        Map<String,Object>map = new HashMap<>();
        map.put("msg",split[0]);
        map.put("username",split[split.length-1]);
        //  split[split.length-1]     接受信息的客户端
        //  "/queue/msg"              队列
        simpMessagingTemplate.convertAndSendToUser(split[split.length-1],"/queue/msg",map);
    }
}
复制代码

前段

这里就不对前段进行相关的介绍了,大致描述下

<template>
  <div>
    <div style="margin-top: 20px">
      <div v-for = "(m,index) in ms" :key="index">{{m.username}}:{{m.msg}}</div>
    </div>
    <el-input v-model="msg"></el-input>
    <!-- 通过点击触发sendMsg() 方法来向后台发送数据 -->
    <el-button @click = "sendMsg">发送</el-button>
  </div>
</template>

<script>
  //获取JS
  import '../../lib/sockjs'
  import '../../lib/stomp'

  export default {
    name: "FriendChat",
    data(){
      return {
        msg:'',
        ms:[],
        stomp:null
      }
    },
    mounted(){
      //页面渲染的时候就通过initCon() 方法获取到连接
      this.initCon();
    },
    methods:{
      initCon(){
        let _this=this;
        this.stomp = Stomp.over(new SockJS('/ws/ep'));
        this.stomp.connect({},success => {
          _this.stomp.subscribe("/user/queue/msg",msg =>{
            _this.ms.push(JSON.parse(msg.body));
          })
        },fail =>{

        })
      },
      sendMsg(){
        this.stomp.send("/ws/chat",{ },this.msg)
      }
    }
  }
</script>

<style scoped>
</style>
复制代码

效果

这里通过两个不同的用户来发送信息测试

通过控制台确保协议已升级且获得连接


输入字符串,通过分号将接受者的信息分开

另一边则收到了发送过来的信息