socket.io初体验之简易聊天室

websocket

随着信息技术的飞速发展,对数据的实时性有着更高的追求,传统的信息通信,通常是客户端通过浏览器发出一个请求,然后服务器端在接收请求处理后并将结果返回给客户端,浏览器再将信息更新展示出来。也就是说只能浏览器主动发起请求,才能获取数据的更新。这种数据的获取方式在一些对数据实时性要求较高的业务中就显得不适用了,比如常见的股票交易等。
在早期,为了能够不断地获取服务器的更新,人们通常采用轮循的方式,浏览器不断地向服务器端发送请求,比如每隔几秒钟就请求一次,这种方式虽然能够近似地获取数据的实时更新,但是加大了服务器的压力。而且,没办法知道服务器数据是否已经更新,只能固定地去请求,如果服务器数据没有更新,那么增加了很多的无效请求。
因此,由于这种方式的局限性,人们希望找到一种新的通信方式,不需要客户端发起请求,服务器端在数据更新时能够主动发送数据到客户端,从而实现数据的实时更新,而且避免了很多无效请求。这就是websocket技术。 Socket.IO是一个基于 Node.js 的实时应用程序框架,在即时通讯、通知与消息推送,实时分析等场景中有较为广泛的应用。在本文中我们会搭建一个简单的聊天室,实现socket.io的常见功能。

socket.io

socket.io需要在服务器端和客户端同时进行设置,实现双向连接,其主要步骤如下:

  1. 先从服务器端说起。服务器端先初始化Socket,然后与端口绑定(bind),对端口进行监听(listen),调用accept阻塞,等待客户端连接。
  2. 在这时如果有个客户端初始化一个Socket,然后连接服务器(connect),如果连接成功,这时客户端与服务器端的连接就建立了。
  3. 客户端发送数据请求,服务器端接收请求并处理请求,然后把回应数据发送给客户端,客户端读取数据,最后关闭连接,一次交互结束。 加下来我们就按照上面的顺序搭建一个简易的聊天室。

具体实现

  1. 服务器端初始化:
const socket = require('socket.io');
const server = app.listen('8000',() => {
    console.log('服务器正在8000端口运行');
});
// 设置socket.io
const io = socket(server);  // 将server服务器传递给socket
io.on('connection',(socket) => {
    console.log('a user connected');
})
  1. 客户端初始化socket: 客户端初始化一个Socket,然后连接服务器(connect),如果连接成功,这时客户端与服务器端的连接就建立了。
<script src = "https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.3.0/socket.io.js"></script>
<script>
  var socket = io.connect('http://localhost:8000');
</script>

客户端引入socket.io.js会暴露一个io对象,通过io对象提供的connect方法连接。客户端和服务器端建立好连接之后,客户端就可以像服务器端发送数据了。

  1. 客户端发送数据请求:
btn.addEventListener('click',() => {
    // 实现客户端向服务器发送数据
    socket.emit('chat',{
        message:message.value,
        handle:handle.value
    })
});
  1. 服务器端接收请求并处理请求,然后把回应数据发送给客户端。
io.on('connection',(socket) => {
    // 获取从客户端发送过来的数据
    socket.on('chat',(data) => {
      io.sockets.emit('chat',data)
    });
})
  1. 客户端读取数据
socket.on('chat',(data) => {
    feedback.innerHTML = "";
    output.innerHTML += `<p><strong>${data.handle}:${data.message}</strong></p>`
})

到目前为止,一次完整的交互结束。我们实现的是客户端的数据,服务器端会向所有的客户端(包括自己)进行发送,但是有时候我们不希望向自己发送,比如正在输入中...这种信息只能其他的客户端可见,对自身是不可见的,socket.io提供了广播事件,通过socket.broadcast.emit可以向除自己以外的客户端发送数据。 最终实现的效果如下: 简易聊天室

具体的实现可查看github