一直以来及时通讯是一个听起来就很麻烦的开发项目,现在有一个socket.io很好的解决了轻量级的即时通讯功能。
socket.io 是一个为实时应用提供跨平台实时通信的库。socket.io 旨在使实时应用在每个浏览器和移动设备上成为可能,模糊不同的传输机制之间的差异。
socket.io 的名字源于它使用了浏览器支持并采用的 HTML5 WebSocket 标准,因为并不是所有的浏览器都支持 WebSocket ,所以该库支持一系列降级功能:
- Websocket
- Adobe® Flash® Socket
- AJAX long polling
- AJAX multipart streaming
- Forever Iframe
- JSONP Polling
在大部分情境下,你都能通过这些功能选择与浏览器保持类似长连接的功能。
今天上手玩了玩以前说要学习的NodeJS和这个socket.io,发现使用起来非常的方便,做一些简单的稳定性要求不是很高的项目还是很不错的。
比如在一个项目中看见过一个功能,多人合作编辑同一份文档的时候可以看到该份文档正被谁编辑,防止出现多次提交覆盖的问题。
按照官网的指引完成了一个聊天室项目:https://socket.io/get-started/chat/
代码这里贴一下,这个不是主要问题。
index.js
var app = require('express')();
var http = require('http').Server(app);
var io = require('socket.io')(http);
var count = 1;
app.get('/', function(req, res){
res.sendFile(__dirname + '/index.html');
});
io.on('connection', function(socket){
io.emit('user count', 'Current users: '+count ++);
socket.on('chat message', function(msg){
io.emit('chat message', msg);
});
socket.on('disconnect', function(){
io.emit('user count', count --);
});
});
http.listen(3000, function(){
console.log('listening on *:3000');
});
index.html
<!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: 90%; margin-right: .5%; }
form button { width: 9%; background: rgb(130, 224, 255); border: none; padding: 10px; }
#messages { list-style-type: none; margin: 0; padding: 0; }
#messages li { padding: 5px 10px; }
#messages li:nth-child(odd) { background: #eee; }
</style>
</head>
<script src="/socket.io/socket.io.js"></script>
<script src="https://cdn.bootcss.com/jquery/3.3.1/jquery.min.js"></script>
<script>
$(function () {
var socket = io();
$('form').submit(function(){
socket.emit('chat message', $('#nickname').val() + " said: " + $('#m').val());
$('#m').val('');
return false;
});
socket.on('user count', function(msg){
$('#userCount').html(msg);
});
socket.on('chat message', function(msg){
$('#messages').append($('<li>').text(msg));
});
});
</script>
<body>
<p id="userCount"></p>
<p><input placeholder="nick name ... " id="nickname"/></p>
<ul id="messages"></ul>
<form action="">
<input id="m" autocomplete="off" /><button>Send</button>
</form>
</body>
</html>
没有做任何美化,旨在了解功能,我想要说明的是下面的问题;
上面的html文件是直接在项目中的,用户访问服务器就可以看到这个页面,但是用户如果直接ctrl+s保存页面,然后改改var socket = io(SERVER_IP:PORT);
,然后直接在本地打开html文件,我发现也是可以直接连上服务器的,那么是不是任何一个人都可以参与到这个聊天室并且可以用自己修改的客户端来连接呢?
这里我们就需要做一些处理,如何鉴权是重要的问题,要不然用自己的客户端就可以随便搞服务器了。现在的想法是这样:
- 登录操作。原有网站肯定会有一个登录操作,在登录操作通过之后,可以通过cookie设置一个随机字符串作为token,用户离线之后销毁token。
- 以后客户端所有的emit操作(涉及到向服务器发数据的)都将这个token带到数据里进行校验,校验通过后就可以进行下一步操作,这样就能能够避免不登录就用自己改的客户端上传数据的行为。
- 另一个问题是,如果用户登录之后再从cookie中将自己的token拷贝出来然后用自己客户端操作怎么办呢?这个时候token是合法的,但是客户端是非法的。
https://www.npmjs.com/package/session.socket.io