WebSocket+SpringBoot聊天室(一)

目录

 

1.项目展示

2.知识要点

3.用户列表


1.项目展示

具体功能:

进入聊天室之前,需要先输入用户名再进入,聊天室中可以进行群聊,或者点击用户列表左边的CheckBox来制定给某些人发信息,或者一个人实现单聊。每个用户进入时会显示“欢迎**进入聊天室”,离开会显示“恭送**离开聊天室”

项目在我上一篇博文中的项目中进行改进:https://blog.csdn.net/Doctor_LY/article/details/81362718

2.知识要点

在上一篇博文的技术上进行改进,我查看了一些资料,补充了一些知识点,然后再对这个项目进行开发。

  • 一个WebSocket对象就是一个管道,一个管道代表一个session(上面三个客户端,其实就是有三条连接服务器的管道)
  • 管道与管道之间我是用Session来区分

整体的思路还是比较简单,上一个项目其实已经实现了群聊,在基础上,我们只需要添加的功能是:

  • 用户列表
  • 用户进入和离开提示
  • 用户单聊和多聊

多聊和单聊就是判断你选择了那个用户,获取该用户的SessionID,然后在广播的时候

根据已经获取的ID,来选择发送给那些用户。

3.用户列表

在登录界面点击提交时,我们需要获取用户输入的用户名。然后传到聊天室界面,聊天室的页面js会访问服务器的WebSocket,此时我们需要把传过去的用户名,一起插到访问WebSocket服务器的URL中。WebScoket服务器再获取这个用户名,用来做用户列表。

登陆页面HTML:




    
    WebSocket
    


    

WebSocket聊天室

用户名:

提交的方法和登陆的方法:

package com.example.websocket.controller;

import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import java.util.Map;

@Controller
public class LoginController {

    @PostMapping("/LoginController")
    public ModelAndView login(@RequestParam("username") String username,
                              Map map){
        map.put("username",username);
        return new ModelAndView("chat",map);

    }

    @GetMapping("/login")
    public ModelAndView client(){
        return new ModelAndView("login");
    }
}

可以看到login方法获取用户名参数后,转到chat页面,因为这里用的是FreeMarker模板引擎,在chat页面中只需要用${username},就可以获取到用户名。chat页面中的js会去访问Websocket,需要携带参数过去。

//判断当前浏览器是否支持WebSocket
    if ('WebSocket' in window) {
        webSocket = new WebSocket('ws://localhost:8080/webSocket?username=' + '${username}');
    } else {
        alert("当前浏览器不支持WebSocket");
    }

然后WebSocket需要获取该参数:

 @OnOpen
    public void onOpen(Session session){
        this.session=session;
        webSockets.add(this);
        //获取用户名
        String s=session.getQueryString();
        String urlUsername=s.split("=")[1];
        try {
            username=URLDecoder.decode(urlUsername,"UTF-8");
        }
        catch (Exception e){
            e.printStackTrace();
        }

        //把SessionID和用户名放进集合里面
        map.put(session.getId(),username);
        System.out.println("有新的连接,总数"+webSockets.size()+"sessionId:"+session.getId()+" "+username);
        String content="欢迎"+username+"进入聊天室!";
        Message message=new Message(content,map);
        send(message.toJson());
    }
private Session session;
private String username;

private static CopyOnWriteArraySet webSockets=new CopyOnWriteArraySet<>();
private static Map map=new HashMap<>();

因为在每一个WebSocket对象中,我们添加了两个属性,一个username一个session,所以对应每一个通道它都有自己的session和username。我们定义一个Map集合来存储session和username,这也方便后期用户离开聊天室去掉该用户。用户访问WebScoket,握手成功后会触发OnOpen方法,这时候我们就要广播说,某某同学进入聊天室了。所以就要在OnOpen方法中,广播了。

在上一个项目中,我们广播信息是直接用字符串来表示信息,在这个项目中,其实也是用字符串,但是是一个JSON字符串,这样方便携带更多信息,而且规范。我们想一下要广播的信息包括哪些内容,1、欢迎**进入聊天室。2、还要一个用户列表,用来及时更新用户列表

定义一个广播信息类:

package com.example.websocket.vo;

import com.google.gson.Gson;

import java.text.DateFormat;
import java.util.Date;
import java.util.Map;

public class Message {

    private String content;

    private Map names;

    private Date date=new Date();

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }


    public void setContent(String name,String msg) {
        this.content = name+" "+DateFormat.getDateTimeInstance().format(date) +":
"+msg; } public Map getNames() { return names; } public void setNames(Map names) { this.names = names; } public String toJson(){ return gson.toJson(this); } private static Gson gson=new Gson(); public Message(String content, Map names) { this.content = content; this.names = names; } public Message() { } }

    public void setContent(String name,String msg) {
        this.content = name+" "+DateFormat.getDateTimeInstance().format(date) +":
"+msg; }

上面这个方法是用来拼装规范信息的,每一条信息会说明是谁发送过来和具体的时间。

一个对象要转成JSON字符串就需要用到Gson。在Maven添加相关的依赖。



     com.google.code.gson
     gson
     2.8.5

把信息拼装到Message对象中,然后转成JSON字符串,就可以广播了。

客户端在websocket.onmessage方法中接收到字符串和解析JSON字符串

webSocket.onmessage = function (event) {

        $("#userList").html("");
        eval("var msg=" + event.data + ";");

        if (undefined != msg.content)
            setMessageInnerHTML(msg.content);

        if (undefined != msg.names) {
            $.each(msg.names, function (key, value) {
                var htmlstr = '
  • ' + '
    ' + '' + '' + '
    ' + '
    ' + '
    ' + ''+value+'' + '
    ' + '
  • ' $("#userList").append(htmlstr); }) } }

    把用户列表解析出来就得到用户列表了。

    你可能感兴趣的:(WebSocket,JavaWeb)