实现一个简单的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>
效果展示
浏览器上打开多个窗口,便可进行对话


浙公网安备 33010602011771号