在正式展开之前,我们先来看看 WebSocket
和 Socket.IO
的相关内容
WebSocket WebSocket
是 HTML5
新增的协议,它的目的是在浏览器和服务器之间建立一个不受限的双向通信的通道,比如说服务器可以在任意时刻发送消息给浏览器,Websocket
协议本质上是一个基于 TCP
的协议,它由通信协议和编程 API
组成,WebSocket
能够在浏览器和服务器之间建立双向连接,以基于事件的方式,赋予浏览器事实通信的能力
既然是双向通信,就意味着服务器端和客户端可以同时发送并响应请求,而不再像 HTTP
的请求和响应,为了建立一个 WebSocket
连接,客户端浏览器首先要向服务器发起一个 HTTP
请求,这个请求和通常的 HTTP
请求不同,包含了一些附加头信息,其中附加头信息 Upgrade: WebSocket
表明这是一个申请协议升级的 HTTP
请求
服务器端解析这些附加的头信息然后产生应答信息返回给客户端,客户端和服务器端的 WebSocket
连接就建立起来了,双方就可以通过这个连接通道自由的传递信息,并且这个连接会持续存在直到客户端或者服务器端的某一方主动的关闭连接
WebSocket API 一个简单的实例,大致流程为打开一个连接,为连接创建事件监听器,断开连接,消息时间,发送消息返回到服务器,关闭连接
1 2 3 4 5 6 7 8 9 10 11 var socket = new WebSocket('ws://localhost:8000' ) socket.onopen = function (event ) { socket.send('socket init' ) socket.onmessage = function (event ) { console .log('Message listener' ) } socket.onclose = function (event ) { console .log('closed' ) } socket.close() }
ws
表示 WebSocket
协议,参数为 url
(以 ws
开头)
onopen
,onclose
,onmessage
方法把事件连接到 Socket
实例上
onmessage
事件提供了一个 data
属性,它可以包含消息的 body
部分(消息的 body
部分必须为一个字符串,可以进行序列化或者反序列化,以便传递更多的数据)
Socket.IO Socket.IO
是 Node.js
当中的一个模块,它是通过 WebSocket
进行通信的一种简单方式,Socket.IO
使用检测功能来判断是否建立 WebSocket
连接,或者是 Ajax long-polling
连接,或 Flash
等,可快速创建实时的应用程序,下面是一个简单的示例
客户端 index.html
如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 <!DOCTYPE html> <html lang ='en' > <head > <meta charset ='UTF-8' > <title > Socket.io</title > </head > <body > <h1 > I Am Socket.IO</h1 > <script src ='./socket.io.js' > </script > <script > var socket=io.connect('ws://localhost:8000' ) </script > </body > </html >
服务端 index.js
如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 var http = require ('http' )var fs = require ('fs' )var sever = http.createServer(function (req, res ) { fs.readFile('./index.html' , function (err, data ) { res.writeHead(200 , { 'Content-Type' : 'text/html' }) res.end(data, 'utf-8' ) }) }).listen(3000 ) var io = require ('socket.io' ).listen(sever)io.socket.on('connection' , function (socket ) { console .log('user conneted' ) socket.on('disconnect' , function ( ) { console .log('user disconnet' ) }) })
向服务器发送数据到客户端
1 2 3 4 io.sockets.on('connection' , function (socket ) { socket.emit('message' , { text :'you have connected' }) })
只要客户端连接,它就将数据发送给每一个新的客户端,而如果想给当前所有的客户端都发送消息,则需要发送广播消息
1 2 3 4 5 6 io.sockets.on('connection' , function (socket ) { socket.emit('message' , { text : 'A new user has connected' }) socket.broadcast.emit('massage' , { text : 'A new user has connected' }) })
接下来需要做的就是客户端先连接 Socket.io
服务器,然后侦听在 'message'
事件上接收的数据,然后做出响应
1 2 3 4 var socket = io.connect('ws://localhost:8000' )socket.on('message' , function (data ) { console .log(`${data.text} ` ) })
在 Angular 项目当中使用 WebSocket 主要是结合 WebSocket
和 rxjs
两者一起使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 import { Injectable } from '@angular/core' import { Observable } from 'rxjs' @Injectable ()export class SocketService { ws: WebSocket constructor ( ) { } createObservableSocket(url: string ): Observable<any > { this .ws = new WebSocket(url) return new Observable( observer => { this .ws.onmessage = (event ) => observer.next(event.data) this .ws.onerror = (event ) => observer.error(event) this .ws.onclose = (event ) => observer.complete() }) } }
当然别忘了在当前 Module
当中进行注册
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 import { SocketService } from './header/socket.service' @NgModule ({ declarations: [ AppComponent, ... ], imports: [ BrowserModule, ... ], providers: [SocketService], bootstrap: [AppComponent] }) export class AppModule {}
最后是导入使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 import { Component, OnInit } from '@angular/core' import { SocketService } from './socket.service' @Component ({ selector: 'app-header' , templateUrl: './header.component.html' , styleUrls: ['./header.component.css' ] }) export class HeaderComponent implements OnInit { messageCount = 0 constructor (public socketService: SocketService ) { } ngOnInit() { this .socketService.createObservableSocket('ws://localhost:8000' ) .map(event => JSON .parse(event)) .subscribe( event => this .messageCount = event.messageCount ) } }