WebSocket初探(socket.io实现简版聊天室)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/weixin_41196185/article/details/82185342

最近一段时间了接触了一些socket编程。这里记录一个简单的入门demo。该demo利用socket.io实现了一个简单的聊天应用。各位看官老爷,且接着看具体的实现方式。

准备工作

本人主要是前端开发,会一点点nodejs。因此这个demo是基于socket.io.js实现的。

B/S服务端

首先,我们在服务端安装socket.io

npm install --save socket.io

B/S客户端

接着,在vue项目中安装socket.io-client

npm install --save socket.io-client

思路

聊天室最基本的功能应该有系统通知,聊天内容等。系统通知针对所有socket连接,即是全局广播;聊天内容则是除当前socket用户的非全局广播。还可能存在系统与某个用户的单独消息互动,这则是单播。本文先不涉及room的概念,高手莫怪。

实现方式

socket服务端

主要代码如下:

var http = require('http');
var express = require('express');

var app = express();
var server = http.createServer(app)
var io = require('socket.io')(server);

server.listen(app.get('port'), function() {
  console.log('Express server listening on port ' + app.get('port'));
});
// 监听socket连接
io.on('connection', function (socket) {
    // 当某用户连上聊天室socket服务时,给他打个招呼
    sendToSingle(socket, {
        event: 'greet_from_server',
        data: `你好${socket.id}`
    })
    // 对其他用户给出通知:某某某加入了聊天室
    broadcastExceptSelf(socket, {
        event: 'new_user_join',
        data: {
            user: socket.id
        }
    })
    // 监听用户发的聊天内容
    socket.on('chat', function (data) {
        // 然后广播给其他用户:某某某说了什么
        broadcastExceptSelf(socket, {
            event: 'new_chat_content',
            data: {
                user: socket.id,
                content: data
            }
        })
    });
    // 监听socket连接断开
    socket.on('disconnect', (reason) => {
        // 广播给其他用户:某某某退出了聊天室
        broadcastExceptSelf(socket, {
            event: 'someone_exit',
            data: {
                user: socket.id
            }
        })
    });
});
// 给当前socket连接单独发消息
function sendToSingle(socket, param) {
    socket.emit('singleMsg', param);
}
// 对所有socket连接发消息
function broadcastAll(param) {
    io.emit('broadcastAll', param)
}
// 对除当前socket连接的其他所有socket连接发消息
function broadcastExceptSelf(socket, param) {
    socket.broadcast.emit('broadcast', param);
}

socket客户端

实现方式也比较简单

import io from 'socket.io-client';
// 创建和管理socket
createSocket() {
    let self = this
    this.socket = io(this.$store.state.config.API_ROOT);
    this.socket.on('connect', function(){
        console.log('连上了')
    });
    // 这里接收服务端发来的单独消息
    this.socket.on('singleMsg', function(msg){
        console.log(msg)
        switch (msg.event) {
            // 如来自服务端的问候,虽然这里没写什么,但是可以据此做一些页面上的效果
            case 'greet_from_server':
                break
            default:
                break
        }
    })
    // 目前还没用到,可拓展
    this.socket.on('broadcastAll', function(msg){
        console.log(msg)
    })
    // 监听广播
    this.socket.on('broadcast', function(msg){
        console.log(msg)
        switch (msg.event) {
            // 新用户加入聊天室
            case 'new_user_join':
                self.msgList.push({
                    time: new Date().toLocaleString(),
                    user: '系统通知',
                    content: `用户 ${msg.data.user} 加入了聊天室......`
                })
                break
            // 用户退出聊天室
            case 'someone_exit':
                self.msgList.push({
                    time: new Date().toLocaleString(),
                    user: '系统通知',
                    content: `用户 ${msg.data.user} 退出了聊天室......`
                })
                break
            // 接收某用户的聊天内容
            case 'new_chat_content':
                self.msgList.push({
                    time: new Date().toLocaleString(),
                    user: msg.data.user,
                    content: msg.data.content
                })
                break
            default:
                break
        }
    })
    this.socket.on('disconnect', function(){
        console.log('连接断开了')
    });
},
// 监听输入框回车事件
onInpuKeyDown(e) {
    console.log(e)
    if (e.keyCode == 13) {
        // 将输入的聊天内容推送给服务端
        this.socket.emit('chat', e.target.value)
        this.msgList.push({
            time: new Date().toLocaleString(),
            user: '我说',
            content: e.target.value
        })
        this.newMsg = ''
    }
}

我们用打开多个窗口的方式模拟多个用户的加入,我这里开了三个窗口,最后的效果大概是这样的。

用户1看到用户2和用户3谈到了很晚的事情
聊天内容1

切到了当前用户2的界面
聊天内容2

切到了当前用户3的界面
聊天内容3

用户3退出了聊天室,在用户2的界面上可以看到推送的系统通知,然后用户2说了一句话也退出了
聊天内容4

用户1看到用户2和用户3的退出情况
聊天内容5

猜你喜欢

转载自blog.csdn.net/weixin_41196185/article/details/82185342