WebSocket简单解释及示例

210 阅读3分钟

假如说我们要开发一个web版的在线聊天系统,我在群里说了一句话,需要所有群成员都能收到这句话,他的难点就是,服务端主动推送消息给客户端,并且客户端需要及时响应。

如果不用websocket,我们有哪些解决的办法?

1、首先我会想到轮询

轮询原理非常简单,让浏览器每隔一秒就像服务端发一次请求,询问是否有新消息。

就是这样婶儿的:

客户端:你好,有我的消息吗?(Request)
服务端:你好,暂时没有。(Response)
客户端:你好,有我的消息吗?(Request)
服务端:你好,没有。(Response)
客户端:你好,有我的消息吗?(Request)
服务端:没有。。。(Response)
客户端:你好,有我的消息吗?(Request)
服务端:好烦啊,没有!(Response)
客户端:你好,有我的消息吗?(Request)
服务端:哼,有啦,给你啦(Response)
客户端:你好,有我的消息吗?(Request)
服务端:没有!!!!(Response)
...

缺点一目了然:不仅浪费资源,而且还需要服务器有很快的处理速度

2、http1.1有这么个东西:long poll

没有用过,他的实现过程也不复杂,其实也是轮询,。客户端发起请求后,如果没有消息,服务端就一直不返回,直到有消息。然后客户端马上再次发起请求,一遍又一遍。。。

就是这样婶儿的:

客户端:你好,有我的消息吗?有了及时告诉我(Request)
服务端:嗯,暂时没有。
(过了两个小时)
服务端:喂,你还在吗,有你的消息了,给你(Response)
客户端:你好,有我的消息吗?(Request)
...

缺点还是一目了然:需要服务器有很强的同时接待客户的能力,也就是高并发。

以上两种方案都有不好的一面,一不小心客户就会收到503、503、503

**想一想,其实都在解决的就是一个问题:处理服务端的被动性。**服务端的特点就是,没有请求我就躺着,有了我就卖力给你解决,哪怕你一秒来一个请求,我也没有抱怨。嗯,没有请求,爷就一直躺着

那么,websocket就闪亮登场了

首先,他就是一种TCP连接协议。

维基百科这样说到: WebSocket使得客户端和服务器之间的数据交换变得更加简单,允许服务端主动向客户端推送数据。在WebSocket API中,浏览器和服务器只需要完成一次握手,两者之间就直接可以创建持久性的连接,并进行双向数据传输。

注意,这里有一个词:“握手”。

就是这样婶儿的:

客户端:喂,现在我不一秒烦你一次了,我现在发的是websocket,帮我找个新助理,不要让那个HTTP再来掺合了
服务端:好的啊,websocket是吧,我知道了,我处理一下。

“握手”完成,至此HTTP的工作结束,以后双方都是遵守websocket来完成工作。

所以,不能说websocket是基于HTTP的,他是个全新的协议,只是借用了一次HTTP来完成握手。和HTTP有交集,但不是全部。


使用示例(nodejs)

假设你已经安装好了nodejs

1、安装nodejs-websocke模块

npm install nodejs-websocket --save -g

2、node后台部分


var ws = require("nodejs-websocket")
var port=3000;
// Scream server example: "hi" -> "HI!!!"
var server = ws.createServer(function (conn) {
	console.log("New connection")
	conn.on("text", function (str) {
		console.log("Received "+str)
		conn.sendText(str.toUpperCase()+"!!!")
    })
	conn.on("close", function (code, reason) {
		console.log("Connection closed")
	})
	conn.on("error", function (err) {
		console.log("handdle error");
		console.log(err);
	})
}).listen(port);
console.log("websocket server listening on port "+port);

3、前台部分

<!doctype html>
<html>
	<head>
		<meta charset="utf-8">
		<title>websocket</title>
	</head>
	<body>
		<h1>echo test</h1>
		<input id="sendText" type="text" />
		<button id="sendBtn">发送</button>
		<div id="recv"></div>
	</body>
	<script type="text/javascript">
		var websocket=new WebSocket("ws://localhost:3000");
		websocket.onopen=function(){
			console.log("websocket open");
			document.getElementById("recv").innerHTML="connected";
		}
		websocket.onclose=function(){
			console.log("websocket close");
			
		}
		websocket.onmessage=function(e){
			console.log(e.data);
			document.getElementById("recv").innerHTML=e.data;
		}
		document.getElementById("sendBtn").onclick=function(){
			var txt=document.getElementById("sendText").value;
			websocket.send(txt);
		}
	</script>
</html>