scoket.io实现群聊、私聊

1、什么是scoketio?

由于浏览器端对HTML5的支持不一,为了兼容所有浏览器,提供卓越的实时的用户体验,并且为程序员提供客户端与服务端一致的编程体验,于是socket.io诞生。
Socket.IO包括了客户端的js和服务器端的nodejs,它的目标是构建可以在不同浏览器和移动设备上使用的实时应用。

2、本质

Socket.io将Websocket和轮询 (Polling)机制以及其它的实时通信方式封装成了通用的接口,并且在服务端实现了这些实时机制的相应代码。也就是说,Websocket仅仅是 Socket.io实现实时通信的一个子集。
它会自动根据浏览器从WebSocket、AJAX长轮询、Iframe流等等各种方式中选择最佳的方式来实现网络实时应用,非常方便和人性化,而且支持的浏览器最低达IE5.5,应该可以满足绝大部分需求了。

3、socket的组成

Socket.IO 由两部分组成:
1.一个服务端用于集成 (或挂载) 到 Node.JS HTTP 服务器: socket.io
2.一个加载到浏览器中的客户端: socket.io-client
3.开发环境下, socket.io 会自动提供客户端。

4、socket的基本使用

提示:由于开发环境下, socket.io 会自动提供客户端。所以我们只需要安装一个socket.io模块即可。
① 新建一个package.json文件
npm init --yes
② 安装express与socket.io模块
cnpm i express socket.io -S

5、群聊实现

后端代码

let app = require("express")();// 获取express模块实例
let http = require('http').Server(app);// 将express模块实例作为回调构建http模块实例
let io = require('socket.io')(http);// 将http模块实例作为回调构建socket.io模块实例

// 使用http模块开启后端服务(原生node+express的结合)
http.listen(3000, function () {
    console.log('listening on http://127.0.0.1:3000')
})

//设置路由,构建后端接口
app.get('/', function (req, res) {
    res.sendFile(__dirname + '/index.html');
})

// 开始监听前端的socket请求连接(前端每次执行一次io()方法就就会发起一次socket请求)
io.on('connection',function(socket){
    console.log('a user connected');
    // 接收客户端发来的数据
    socket.on('chat message',function(msg){
        console.log('message:'+msg);
        io.emit('receiveMessage',msg)
    })
    // 如果是断开socket请求,就会触发下面的代码
    socket.on('disconnect',function(){
        console.log('user disconnect')
    })
})

前端代码

<!doctype html>
<html>

<head>
    <title>Socket.IO chat</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            font: 13px Helvetica, Arial;
        }

        form {
            background: #000;
            padding: 3px;
            position: fixed;
            bottom: 0;
            width: 100%;
        }

        form input {
            border: 0;
            padding: 10px;
            width: 80%;
            margin-right: .5%;
        }

        form button {
            width: 19%;
            background: rgb(130, 224, 255);
            border: none;
            padding: 10px;
        }

        #messages {
            list-style-type: none;
            margin: 0;
            padding: 0;
        }

        #messages li {
            padding: 5px 10px;
        }
    </style>
</head>

<body>
    <ul id="messages">
    </ul>
    <form action="">
        <input id="m" autocomplete="off" /><button>Send</button>
    </form>
</body>
<script src="/socket.io/socket.io.js"></script>
<script>
    // 这样就加载了 socket.io-client。 socket.io-client 暴露了一个 io 全局变量,然后连接服务器。
    //请注意我们在调用 io() 时没有指定任何 URL,因为它默认将尝试连接到提供当前页面的主机。
    var username = prompt('请输入用户名')
    var socket = io('http://localhost:3000');
    var form = document.querySelector('form');
    var val = document.querySelector('#m');
    // var messages=document.querySelector('#messages')
    form.onsubmit = function () {
        var obj = {
            username: username,
            mes: val.value
        }
        socket.emit('chat message', JSON.stringify(obj));
        messages.innerHTML += `
            <li style="text-align:right;color:blue;">${val.value}<li>
        `;
        val.value = '';
        return false;//阻止表单默认行为
    }
    //接收后端发来的消息
    socket.on('receiveMessage', function (data) {
        var obj = JSON.parse(data);
        if (obj.username == username)
            //不渲染自己发送的消息
            return;
        //渲染别人发送的消息
        messages.innerHTML += `
            <li style="text-align:left;color:red;">${obj.username}:${obj.mes}<li>`;
    })
</script>

</html>

效果
在这里插入图片描述

6、私聊

后端

var app = require('express')(); // 获取express模块实例
var http = require('http').Server(app); // 将express模块实例作为回调构建http模块实例
var io = require('socket.io')(http); // 将http模块实例作为回调构建socket.io模块实例

// 使用http模块开启后端服务(原生node+express的结合)
http.listen(3000, function () {
    console.log('listening on http://127.0.0.1:3000')
})
// 设置路由,构建后端接口
app.get('/', function (req, res) {
    res.sendFile(__dirname + '/index.html'); // 将根目录下的index.html发送到前端
})
var users = {}; // 保存所有用户的键值对集合
io.on('connection', function (socket) {
    socket.on('con', function (msg) {
        var obj = JSON.parse(msg) // 获取连接的用户信息
        users[obj.username] = socket.id; // 将当前用户名和对应的链接id进行保存
        console.log('有新的链接,最新用户集合为:', users)
    })
    // 接收客户端发来的数据
    socket.on('chat message', function (msg) {
        var obj = JSON.parse(msg) // 获取连接的用户信息
        console.log('obj:', obj)
        if (users[obj.toWho] == undefined) {
            let respmes = {
                usernamez: '系统信息',
                mes: '抱歉【' + obj.toWho + '】还未上线'
            }
            io.to(socket.id).emit('receiveMessage', JSON.stringify(respmes)); // 将消息发给当前用户
        } else { // 说明目标用户存在
            let respmes = {
                usernamez: obj.username,
                mes: obj.mes
            }
            io.to(users[obj.toWho]).emit('receiveMessage', JSON.stringify(respmes)); // 通过id将信息转发给指定的对象
        }
    })
    // 如果是断开socket请求,就会触发下面的代码
    socket.on('disconnect', function () {
        console.log('user disconnected')
    })
})

前端

<html>

<head>
    <title>Socket.IO chat</title>
    <style>
        * {
            margin: 0;
            padding: 0;
            box-sizing: border-box;
        }

        body {
            font: 13px Helvetica, Arial;
        }

        form {
            background: #000;
            padding: 3px;
            position: fixed;
            bottom: 0;
            width: 100%;
        }

        form input {
            border: 0;
            padding: 10px;
            width: 80%;
            margin-right: .5%;
        }

        form button {
            width: 19%;
            background: rgb(130, 224, 255);
            border: none;
            padding: 10px;
        }

        #messages {
            list-style-type: none;
            margin: 0;
            padding: 0;
        }

        #messages li {
            padding: 5px 10px;
        }
    </style>
</head>

<body>
    <script src="/socket.io/socket.io.js"></script>
    <script>
        // 这样就加载了 socket.io-client。 socket.io-client 暴露了一个 io 全局变量,然后连接服务器。
        //请注意我们在调用 io() 时没有指定任何 URL,因为它默认将尝试连接到提供当前页面的主机。
        window.onload = function () {
            var username = prompt("请输入你的用户名:", "");
            var who = prompt("你要和谁聊天?:", "");
            document.body.innerHTML = `<h3>当前用户:${username}, 和${who}聊天中...</h3>` + document.body.innerHTML;
            var socket = io("http://localhost:3000/");
            var form = document.querySelector("form");
            var val = document.querySelector("#m");
            //先和服务端建立连接
            let conobj = {
                username: username,
                toWho: who,
            }
            socket.emit('con', JSON.stringify(conobj));
            //表单提交事件
            form.onsubmit = function () {
                let obj = {
                    username: username,
                    toWho: who,
                    mes: val.value
                }
                socket.emit('chat message', JSON.stringify(obj));
                messages.innerHTML += `
<li style="text-align:right;color:blue;">${val.value}<li>`;
                val.value = "";
                return false;
            }
            //接收后端发来的消息
            socket.on("receiveMessage", function (data) {
                var obj = JSON.parse(data);
                console.log(obj)
                if (obj.username == username) return; //不接受自己发的消息
                messages.innerHTML += `
<li style="text-align:left;color:red;">${obj.usernamez}:${obj.mes}<li>`;
            })
        }
    </script>
    <ul id="messages"></ul>
    <form action="">
        <input id="m" autocomplete="off" /><button>Send</button>
    </form>
</body>

</html>

效果
在这里插入图片描述

  • 3
    点赞
  • 12
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值