您的位置:首页 > Web前端 > JavaScript

socket基础知识及js中的Web Sockets

2016-07-16 21:17 686 查看

socket基本概念

两个进程如果需要进行通讯最基本的前提是能够唯一的标示一个进程,在本地通讯中用PID来唯一标示一个进程,但PID只在本地唯一,网络中的两个进程PID冲突几率很大。我们知道IP层的ip地址可以唯一标示主机,而TCP层协议和端口号可以唯一标示主机的一个进程,这样我们可以利用ip地址+协议+端口号唯一标示网络中的一个进程。能够唯一标示网络中的进程后,他们就可以利用socket进行通信了。我们经常把socket翻译为套接字,socket是在应用层和传输层之间的一个抽象层,它把TCP/IP层复杂的操作抽象为几个简单的接口供应用层调用已实现进程在网络中的通信。



图片来自Samaritans的简单理解socket

js中的web sockets

为了实现在单独的持久连接上提供全双工、双向通信的功能,HTML5中增加了连接API-WebSockets。在JavaScript中创建了WebSocket之后,会有一个HTTP请求发送到浏览器以发起连接。在取得服务器响应后,建立的连接会使用HTTP升级,从HTTP协议转变为web socket协议。具体的过程如下:

(1)客户端建立连接时,通过HTTP发起请求报文,如下所示

Upgrade:websocket
Connection:Upgrade
Sec-WebSocket-Key:
Sec-WebSocket-Protocol:


这两个字段表示请求服务器端升级协议为WebSocket,Sec-W

(2)服务器端处理完请求之后,响应如下报文

Upgrade:websocket
Connection:Upgrade
Sec-WebSocket-Accept:
Sec-WebSocket-Protocol:


该报文告知客户端正在更换协议,更新应用层协议为WebSocket协议。

web sockets API

要创建Web Socket,先实例一个webSocket对象并传入要连接的URL

var socket = new WebSocket('ws:www.example.com/server.php');


在这里需要注意,必须给WebSocket传入绝对URL。同源策略对Web Sockets不适用,因此可以通过它打开任何站点的连接。所以是否跟某个域中的页面通信,完全取决于服务器

实例化了WebSocket对象后,浏览器会马上尝试创建连接。WebSocket有一个表示当前状态的readyState属性。

WebSocket.OPENING(0):正在创建连接

WebSocket.OPEN(1):已经建立连接

WebSocket.CLOSING(2):正在关闭连接

WebSocket.CLOSING(3):已经关闭连接

readyState的值永远从0开始。

要关闭socket连接,可以在任何时候调用close()方法

socket.close();

发送和接收数据

Web Socket打开之后,就可以通过连接发送和接收数据。要向服务器发送数据,使用send()方法,并传入任意字符串。如

var socket = new WebSocket('ws:www.example.com/server.php');socket.send('hello world');


在这里需要注意:因为WebSockets只能通过连接发送纯文本数据,所以对于复杂的数据结构,在通过连接发送之前,必须进行序列化。

当服务器向客户端发来消息时,WebSocket对象就会触发message事件。这个message事件与其他传递消息的协议类似,也是把返回的数据保存在event.data属性中

socket.onmessage = function(e){
var data = e.data;
//处理数据
};


值得一提的是data的数据格式也是字符串,如果想得到其他格式的数据,必须手工解析这些数据。

其他事件

WebSocket对象还有其他三个事件,在连接声明周期的不同阶段触发

open:在成功建立连接时触发

error: 在发生错误时触发,连接不能持续

close:在连接关闭时触发

WebSocket对象不支持DOM2级事件侦听器,因此必须使用DOM0级语法分别定义每个事件处理程序。

在这三个事件中,只有close事件的event对象有额外的信息。这个事件的事件对象有三个额外的属性:wasClean、code和reason。其中,wasClean是一个布尔值,表示连接是否已经明确的关闭;code是服务器返回的数值状态码;而reason是一个字符串,包含服务器发回的信息。可以将这些信息显示给用户。

socket.onclose = function(event){

console.log(‘was clean?’+event.wasClean+’code=’+event.code+’reason=’+event.reason);

}

利用socket.io实现简易聊天室

实现聊天室的主要过程如下

客户端通过发送io.connect(url)连接请求与服务器端进行连接(若不适用socket.io库,使用new WebSocket(url)可以发送连接请求)

服务器端通过监听‘connection’事件处理连接请求io.on(‘connection’,function(socket){//发送open事件})

客户端通过监听open事件确认是否与服务器端进行连接

客户端通过send方法向服务器端发送信息

服务器端通过监听message方法监听send的发送信息,并处理发送信息(将信息广播给其他聊天室成员和自己)

服务器端通过监听disconnect方法判断客户端请求是否断开

socket.io中emit的几种方式

socket.emit(‘message’,data)信息传输对象为当前socket对应的client,各个client socket相互不影响

socket.broadcast.emit信息传输对象为所有client,排除当前socket对应的client

io.socket.emit信息传输的对象为所有的client

其完整代码参见我的github:https://github.com/charlene0824/chat
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  javascript