实现一个简单的WebSocket聊天室

Websocket简介

WebSocket 是 HTML5 开始提供的一种在单个 TCP 连接上进行全双工通讯的协议。
WebSocket 使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在 WebSocket API 中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。
在 WebSocket API 中,浏览器和服务器只需要做一个握手的动作,然后,浏览器和服务器之间就形成了一条快速通道。两者之间就直接可以数据互相传送。

为什么传统的HTTP协议不能做到WebSocket实现的功能?这是因为HTTP协议是一个请求-响应协议,请求必须先由浏览器发给服务器,服务器才能响应这个请求,再把数据发送给浏览器。换句话说,浏览器不主动请求,服务器是没法主动发数据给浏览器的。

 

使用Socket.io

Socket.io是一个WebSocket库,包括了客户端的js和服务器端的nodejs,它的目标是构建可以在不同浏览器和移动设备上使用的实时应用。它会自动根据浏览器从WebSocket、AJAX长轮询、Iframe流等等各种方式中选择最佳的方式来实现网络实时应用,非常方便和人性化,而且支持的浏览器最低达IE5.5

socket.io特点

  • 实时分析:将数据推送到客户端,这些客户端会被表示为实时计数器,图表或日志客户。
  • 实时通信和聊天:只需几行代码便可写成一个Socket.IO的”Hello,World”聊天应用。
  • 二进制流传输:从1.0版本开始,Socket.IO支持任何形式的二进制文件传输,例如:图片,视频,音频等。
  • 文档合并:允许多个用户同时编辑一个文档,并且能够看到每个用户做出的修改。

具体事件和方法参见:https://www.w3cschool.cn/socket/

后端代码

使用node.js + express快速搭建一个服务器,引入Socket.io ,代码如下:

var app = require("express")();
var http = require('http').Server(app);
//引入socket.io
var io = require('socket.io')(http);
//加载前端页面
app.get('/',function(req,res){
  res.sendFile(__dirname + '/index.html');
});
//连接socket
var userName = '';
io.on('connection',function(socket){
  console.log('a user connected:'+socket.id);
  userName = socket.id.substr(0,10);
  socket.broadcast.emit('chat message','欢迎用户: ' + userName + '加入房间'); 
  socket.on('disconnect',function(){
    console.log('user disconneted');
  });

  socket.on('chat message',function(data){  
    io.emit('chat message',data);
    console.log('message : ' + data.msg);
  });
});

http.listen(3000,function(){
  console.log('listening on *:3000');
});

  

前端代码

<!doctype html>
<html>

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

    body {
      font: 13px Helvetica, Arial;
    }

    form {
      padding: 3px;
      position: fixed;
      bottom: 0;
      width: 100%;
      border-top: 1px solid gray;
    }

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

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

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

    #messages li {
      padding: 5px 10px;
      height: 40px;
      line-height: 30px;
    }

    #messages li:nth-child(odd) {
      background: #eee;
    }
	.all_msg{
	  text-align:center;
	}
	.my_msg{
	  text-align:right;
	}

    .websocket {
      width: 400px;
      height: 800px;
      position: absolute;
      top: 5%;
      left: 50%;
      transform: translateX(-50%);
      background: #f7f7f7;
      border: 1px solid gray;
    }
  </style>
</head>

<body>
  <div class="websocket">
    <ul id="messages"></ul>
    <form action="">
      <input id="m" autocomplete="off" /><button>Send</button>
    </form>
  </div>
</body>

<script src="/socket.io/socket.io.js"></script>
<script src="http://lib.sinaapp.com/js/jquery/1.7.2/jquery.min.js"></script>
<script>
  var socket = io();
  var userName = '';
  socket.on('connect', () => {
    userName = socket.id.substr(0, 10);
    console.log(userName)
  });
  $('form').submit(function () {
    var msg = $('#m').val();
    socket.emit('chat message', { msg, userName });
    $('#m').val('');
    return false;
  });

  socket.on('chat message', function (data) {
    if (typeof data == 'string') {
      $('#messages').append(`<li class="all_msg">${data}</li>`);//广播
    } else {
      if (userName == data.userName) {
        $('#messages').append(`<li class="my_msg"><span>${data.msg}</span>:<span>我</span></li>`);
      } else {
        $('#messages').append(`<li><span>${data.userName}</span>:<span>${data.msg}</span></li>`);
      }

    }
  });
</script>

</html>

  

效果展示

浏览器上打开多个窗口,便可进行对话

 

posted @ 2020-11-02 10:59  北巷听雨  阅读(253)  评论(0编辑  收藏  举报
返回顶端