websocket实现简单的消息发送

发布时间 2023-11-27 16:00:04作者: 小-伙计

websocket:

 

 

效果图

 前端代码

html部分

<div>
        <!--      <div style="float: left;height: 100vh;width: 1%"></div>-->
        <div style="float: left;width: 20%;height: 96vh;border-radius: 0.5rem;">
            <div class="el-dropdown-link" style="margin-left: 1.6vh;margin-top: 0.7vw;margin-bottom: 0.7vw">返回</div>
            <div class="info" style="height: 9vh;width: 100%;text-align: center;border-radius: 10px;">
                <div style="width: 95%;height: 8vh;border-radius: 0.5rem;margin-left: 3vw;">
                    <div style="float: left">
                        <img style="border-radius: 50%;height: 7vh;width: 3.5vw;margin-left: 1rem;margin-right: 0.7rem;margin-top: 1vh;" src="https://cloud-secondhand-trading.oss-cn-shanghai.aliyuncs.com/u%3D3030190913%2C291621981%26fm%3D253%26fmt%3Dauto%26app%3D138%26f%3DJPEG.webp">
                    </div>
                    <div style="float: left;margin-top: 2vh;font-size: 2.5vh">
                        {{ userName }}
                    </div>
                </div>
            </div>
            <hr/>
            <div style="height: 4vh;width: 100%;text-align: center">
                <div style="margin-top: 2vh;font-weight: bold;font-size: 2.5vh">消息列表</div>
            </div>
            <hr/>
            <div v-for="(name,index) in userList" :key="name.id">
                <div :id="'id'+name.id" class="messagediv" style="width: 95%;height: 7.7vh;border-radius: 0.5rem;" tabindex="2" @click="getStyMessage(name)">
                    <div style="float: left">
                        <img style="border-radius: 50%;height: 6.3vh;width: 3vw;margin-left: 1rem;margin-right: 0.7rem;margin-top: 5px;" src="https://cloud-secondhand-trading.oss-cn-shanghai.aliyuncs.com/u%3D3030190913%2C291621981%26fm%3D253%26fmt%3Dauto%26app%3D138%26f%3DJPEG.webp">
                    </div>
                    <div style="float: left;margin-top: 2vh;font-size: 2.5vh">
                        {{ name.sender }}
                    </div>
                </div>
                <div style="width: 19.5vw">
                    <hr v-if="index!=list.length-1"
                        style="font-size: 0.001rem;margin-left: 9vh;color: gray;width: 70%;top: -10px"/>
                </div>
            </div>
        </div>
        <div style="float: left;height: 96vh;width: 0.5%"></div>
        <div style="float: left;width: 78%;background-color: rgb(250,250,249);height: 96vh;">
            <div style="width: 100%;height: 3rem;float: left;
          text-align: center;background-color: #f0f0f0;border-radius: 0.5rem;">
                <div style="margin-top: 0.8rem;font-size: 2.5vh">{{name}}</div>
            </div>
            <div style="float: left;clear: left;width: 100%;margin-top: 0.8rem;height: 80vh;overflow: auto">
                <div v-for="message in list" :key="message.id">
                    <div style="text-align: center;width: 100%;font-size: 1.6vh;">{{ message.date }}</div>
                    <div v-if="message.sender!=userName" style="width: 100%;height: 3rem">
                        <div style="float: left">
                            <img style="border-radius: 50%;height: 6.3vh;width: 3vw;margin-left: 4rem;margin-right: 0.7rem" src="https://cloud-secondhand-trading.oss-cn-shanghai.aliyuncs.com/u%3D3030190913%2C291621981%26fm%3D253%26fmt%3Dauto%26app%3D138%26f%3DJPEG.webp">
                        </div>
                        <div>
                            <!--                      <div style="margin-left: 0.7rem;font-size: 0.5rem">nih</div>-->
                            <div style="float: left;background-color: white;height: 4.6vh;;border-radius: 10px;margin-top: 0.9vh">
                                <div style="margin-left: 0.8vw;margin-right: 0.8vw;margin-top:0.68vh;font-size: 2.5vh">{{message.message}}</div>
                            </div>
                        </div>
                    </div>
                    <div v-if="message.sender==userName" style="width: 100%;height: 3rem">
                        <div style="float: right">
                            <img style="border-radius: 50%;height: 6.3vh;width: 3vw;margin-right: 4rem;margin-left: 0.7rem" src="https://cloud-secondhand-trading.oss-cn-shanghai.aliyuncs.com/u%3D3030190913%2C291621981%26fm%3D253%26fmt%3Dauto%26app%3D138%26f%3DJPEG.webp">
                        </div>
                        <div>
                            <!--                      <div style="margin-left: 0.7rem;font-size: 0.5rem">nih</div>-->
                            <div style="float: right;background-color: cornflowerblue;height: 4.6vh;border-radius: 10px;margin-top: 0.4rem;">
                                <div style="margin: 0.27rem;margin-left: 0.7rem;margin-right: 0.7rem;font-size: 2.5vh">{{message.message}}</div>
<!--                                <div style="font-size: 1.8vh;margin-left: 0.5rem;color: gray;margin-top: 0.2rem">-->
<!--                                    <span v-if="true">已读</span>-->
<!--                                    <span v-if="false">未读</span>-->
<!--                                </div>-->
                            </div>
                        </div>
                    </div>
                </div>
                <div style="width: 100%;height: 4vh"></div>
            </div>
            <div v-if="name!=''" style="clear: left;position:absolute;bottom: 10px;width: 100%;height: 5vh;background-color: white">
                    <input v-model="message" type="text" name="message" style="float: left;width: 55%;margin-left: 7vw;height: 4.7vh;border-radius: 0.5rem;">

                <div style="float: left">

                    <input @click="addMessage" value="发送" type="button" style="height: 5vh;width: 5vw;border-radius: 0.5rem;margin-left: 0.7vw;
                font-size: 2.5vh;margin-top: 0.1vh;"/>
                </div>
            </div>
        </div>
    </div>

js部分

mounted部分:页面加载就连接,然后就实时接收消息
mounted() {
        var socket = new WebSocket("ws://localhost:8818/ws/2");
        console.log(this)
        const data = this;
        socket.onmessage = function(event) {
            data.setMessage( name, event.data )
            console.log("收到服务器消息: " + event.data);
            console.log(data);
        };
    },

 方法部分

// 接收消息
        setMessage(name,message){
            console.log(this.list)
            //date: "2023-10-26T14:06:06.387", read: 0, sender: "李四", name: "张三", id: 1, message: "你好2
            this.list.push({date: new Date(),read: 0,sender: this.userName,name: name,id: this.list.length+1, message: message })
            this.getMessages();
        },
// 发送消息
        addMessage(){
            var i =1;
            console.log(this.list)
            const message = this.message;
            if (message!=null&&message!=''){
                this.$http.post('/api/cloud-member/member/webSocket',{
                    'id': this.id,'message':message,'name':this.name,sender: this.userName
                }).then(response => {
                    console.log(response);
                    if (i<=1){
                        // 请求成功处理
                        this.getMessages();
                        const date = new Date();
                        console.log(new Date());
                        console.log(this.date);
                        if (date.getTime()-this.date>=300000){
                            var month = date.getMonth() + 1
                            const year = date.getFullYear()+"-"+month+"-"+date.getDate()+" "
                                +date.getHours()+":"+date.getMinutes();
                            this.list.push({date: year, read: 0,sender: this.userName, name: this.name, id: this.list.length+1, message: message});
                        }else{
                            this.list.push({date: '', read: 0,sender: this.userName, name: this.name, id: this.list.length+1, message: message});
                        }
                        // this.getMessage({name: this.userName,sender: this.name})
                        i++;
                    }
                }).catch(error => {
                    // 请求失败处理
                    console.log(error);
                });
            }

            this.message = '';
        },
     getMessage(name){
            // console.log(name);
            // this.getMessages();
            this.name = name.sender
            this.list = [];


        },
        // 修改时间
        getDateTime(name){
            this.lists.forEach(list=>{
                if ((list.sender==name.sender&&list.name==name.name)||(list.sender==name.name&&list.name==name.sender)){
                    // 5分钟 300000
                    let date = new Date(list.date).getTime();
                    console.log(date)
                    if (date-this.date>300000){
                        this.date = date;
                        list.date = list.date.substring(0,16).replace('T',' ');
                        // if (id==1){
                        //     //date: "2023-10-26T14:06:06.387", read: 0, sender: "李四", name: "张三", id: 1, message: "你好2
                        //     this.list.push({date: item.date,read: item.read,sender: this.userName,name: this.name,id: this.list.length+1, message: item.message,})
                        // }
                    }else{
                        list.date = '';
                    }
                    //date: "2023-10-26T14:06:06.387", read: 0, sender: "李四", name: "张三", id: 1, message: "你好2
                    this.list.push({date: list.date, read: 0,sender: list.sender, name: list.name, id: this.list.length+1, message: list.message});
                    console.log(this.list)
                }
            })
        },
        getStyMessage(name){
            // console.log(name);
            this.getMessages();
            this.name = name.sender
            this.list = [];
            this.getStyle(name.id)
            this.getDateTime(name);

        },
     // 消息列表选中变颜色 getStyle(id){ let classNames = document.getElementsByClassName("messagediv"); for (let i = 0; i < classNames.length; i++) { classNames[i].style.backgroundColor = "white" } const ids = document.getElementById("id"+id); ids.style.backgroundColor = "#e1e1e1"; }, getMessages(){ this.$http.get('/api/cloud-member/member/getMessage/'+this.userName).then(response => { // console.log(Array.from(response.data.data)); const m = response.data.data; if (Array.from(m).length>0){ const list = Array.from(response.data.data); this.lists = list; } this.userList = []; const set = new Set(); this.lists.forEach(item=>{ // 必须要跟我聊过天的才显示 过滤掉自己 if (item.sender==this.userName||item.name==this.userName){ if (item.sender!=this.userName){ set.add(item.sender) } } }) const name = Array.from(set) for (let i = 0; i < name.length; i++) { this.userList.push({id: i+1,sender: name[i],name:this.userName}); } }).catch(error => { // 请求失败处理 console.log(error); }); } 

 后端java代码

websocket类

/**
 * WebSocket服务
 */
@Component
@ServerEndpoint("/ws/{sid}")
public class WebSocketServer {

    //存放会话对象
    private static Map<String, Session> sessionMap = new HashMap();
    private Map<String, Object> map = new HashMap();
    private List<String> list = new ArrayList<>();

    /**
     * 连接建立成功调用的方法
     */
    @OnOpen
    public void onOpen(Session session, @PathParam("sid") String sid) {
        System.out.println("客户端:" + sid + "建立连接");
        list.add(session.getId());
        sessionMap.put(sid, session);
    }

    /**
     * 收到客户端消息后调用的方法
     *
     * @param message 客户端发送过来的消息
     */
    @OnMessage
    public void onMessage(String message, @PathParam("sid") String sid) {
        map.put(sid,(map.get(sid)==null?"":(map.get(sid)+","))+message);

        System.out.println("收到来自客户端:" + sid + "的信息:" + map);
    }

    /**
     * 连接关闭调用的方法
     *
     * @param sid
     */
    @OnClose
    public void onClose(@PathParam("sid") String sid) {
        System.out.println("连接断开:" + sid);
        sessionMap.remove(sid);
    }

    /**
     * 群发
     *
     * @param message
     */
    public void sendToAllClients(String message) {
        Collection<Session> sessions = sessionMap.values();
        for (Session session : sessions) {
            try {
                //服务器向客户端发送消息
                session.getBasicRemote().sendText(message);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }
    /**
     * 私发
     *
     * @param message
     */
    public void sendToAllClient(String id,String message) {
        Session session = sessionMap.get(id);
        if (session != null) {
            try {
                // 向客户发送消息
                session.getBasicRemote().sendText(message);
            } catch (Exception e) {
                e.printStackTrace();
            }
        } else {
            System.out.println("找不到该客户的会话信息");
        }
    }

} 

websocket配置类

/**
 * @Author: xhj
 * @Date: 2023/10/23/20:15
 * @Description:
 */
/**
 * WebSocket配置类,用于注册WebSocket的Bean
 */
@Configuration
public class WebSocketConfiguration {

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

}

  

发送消息

@PostMapping("/webSocket")
    public R webSocket(@RequestBody Map<String,Object> objectMap){
//        Map<String, Object> map = new HashMap<>();
//        map.put("id",objectMap.get("id"));
//        map.put("message",objectMap.);
//        map.put("sender",sender);
//        map.put("name",name);
        objectMap.put("date", LocalDateTime.now());
        objectMap.put("read",0);
        //基于WebSocket实现发送消息
        webSocketServer.sendToAllClient(objectMap.get("id")+"", objectMap.get("message")+"");
        objectMap.put("id",list.size()+1);
        list.add(objectMap);
        return R.ok(list);
    }

 获取消息

@GetMapping("/getMessage/{sender}")
    public R getMessage(@PathVariable("sender") String sender){
        List<Map<String,Object>> list1 = new ArrayList<>();
        for (Map<String, Object> map : list) {
            if (map.get("sender").equals(sender)||map.get("name").equals(sender)){
                list1.add(map);
            }
        }
        System.out.println(list1);
        return R.ok(list1);
    }

因为没有对接数据库所以我就使用了map来放数据

private List<Map<String,Object>> list = new ArrayList<>();

    public MemberController(){
        HashMap<String, Object> map = new HashMap<>();
        map.put("id",this.list.size()+1);
        map.put("message","你好2");
        map.put("sender","李四");
        map.put("name","张三");
        map.put("date", LocalDateTime.now());
        map.put("read",0);
        HashMap<String, Object> map2 = new HashMap<>();
        map2.put("id",this.list.size()+1);
        map2.put("message","你好2");
        map2.put("sender","张三");
        map2.put("name","李四");
        map2.put("date", LocalDateTime.now());
        map2.put("read",0);
        HashMap<String, Object> map3 = new HashMap<>();
        map3.put("id",this.list.size()+1);
        map3.put("message","你好2");
        map3.put("sender","张三");
        map3.put("name","王五");
        map3.put("date", LocalDateTime.now());
        map3.put("read",0);
        list.add(map);
        list.add(map2);
        list.add(map3);
    }

现在能简单的通讯了,最重要的是理解,有可能放入你的电脑执行会有bug

如果你对接数据库,前端就不需要写这么麻烦了

后续我对此进行了优化和对接数据库,最重要的就是websocket类里面的几个方法,最后我前端写了个websocket.js,全局使用。