訊息的即時推送——net實現、websocket實現以及socket.io實現

Cymiran發表於2019-02-16

即時通訊

即時通訊是一種客戶端與服務端的通訊服務,例如聊天,訊息推送等,方式有三種:

  • node內建net模組實現的通訊方式
  • WebSocket的通訊方式
  • Socket.io的通訊方式

這三種通訊方式都很類似,
服務端:

1、建立服務
2、建立連線 拿到客戶端資訊
3、服務端廣播資料給各個客戶端
4、服務端關閉連線

客戶端:

1、客戶端連線伺服器
2、客戶端傳送資料
3、客戶端接受服務端資料

Websocket實現簡單聊天視窗

1、服務端 新建檔案WsServer.js

//1、建立服務
var WebsocketServer = require(`ws`).Server
var wss = new WebsocketServer({port: 9000})
//
var clientMap = new Object()
var i = 0
wss.on(`connection`,funciton(ws){
    console.log(ws + `上線啦`)
    ws.name = ++i
    clientMap[ws.name] = ws
    //接收客戶端資料
    ws.on(`message`,function(msg){
        broadcast(msg, ws)
    })
    //客戶端關閉監聽
    ws.on(`close`,function(){
        delete clientMap[ws.name]
        console.log(ws.name + `離開`)
    })
})
function broadcast(msg, ws){
    for(var key in clientMap){
        clientMap[key].send(ws.name + `說` + msg)
    }
}

2、客戶端 新建html頁面

index.html
<h1>Websocket</h1>
<div id=`chatroom`></div>
<input type="text" name= "sayinput" id=`sayinput` value/>
<input type="button" name="send" id="send" value="傳送">

<script src="./wsClient.js"></script>
<script>
    function send(){
        var sayinput = document.querySelector(`#sayinput`)
        ws.send(sayinput.value)      //傳送資訊
        sayinput.value = ``
    }
    document.querySelector(`#send`).onclick = function(){
        send()
    }
    document.body.onkeup = function(event){
        if(event.keyCode == 13){
            send()
        }
    }
</script> 

3、客戶端wsClient.js

var ws = new WebSocket(`ws://10.0.0.1:9000/`)
ws.onopen = function(){
    ws.send(`大家好`)
}
ws.onmessage = function(event){
    var chatroom = document.querySelector(`#chatroom`)
    chatroom.innerHTML += `<br/>` + event.data
}
ws.onclose = function(){
    console.log(`closed`)
}
ws.onerr = function(err){
    console.log(err)
}

在html中引入wsClient.js
啟動服務端 node WsServer.js
npm init 
cnpm i ws -D  

socket.io

Websocket畢竟是H5新出的,有瀏覽器的相容性,所以我們一般用socket.io這種通訊方式,支援websocket的通訊協議,又可以相容ie瀏覽器

(1) 服務端
啟動一個node服務,並繫結connection事件來連結客戶端
www 中配置

var http = require(`http`)
var server = http.createServer(app)  //啟動一個服務

var io =  require(`socket.io`)(server)
var broadcast = require(`./broadcast`)
var clients = {}
var count = 0;
io.on(`connection`,(socket)=>{
    socket.name = ++count;
    clients[socket.name] = socket
    
    socket.on(`disconnect`,()=>{
        delete clients[socket.name]     //斷開連結
    })
})

//如何將伺服器的資料派發到各個客戶端呢,我們這裡定義一個broadcast中間事件

broadcast.js

const EventEmitter = require(`events`).EventEmitter
let broadcast = Object.assign({},EventEmitter.prototype)
module.exports = broadcast

www

broadcast.on(`hahaha`,function(message){    //將服務端的資訊分發給各個客戶端
    for(var name in clients){
        clients[name].send(message)
    }
})

//如何使用呢?當服務端有新的訊息時,我們應該如何訂閱到客戶端

這裡,如果我新新增一條商品,客戶端要實時接收到有新商品了
willSaveProducts.save().then(()=>{
    broadcast.emit(`hahaha`,`xin`)
    console.log(`新增成功`)
    res.json(getParam({success:true}))
})

(2) 客戶端
定義bus匯流排,進行傳參

import Vue from `vue`
const event_bus = new Vue()
export default event_bus

建立連結 並接受服務端傳過來的資訊

import bus from `../event_bus`
const socket = io.connect(`http://localhost:3000`)

socket.on(`message`,(message)=>{
    bus.$emit(message)
})

元件 呼叫 接收傳過來的引數 根據引數來響應

main.vue

import bus from `../../event_bus`

export default {
    data(){
        return {
            isHasNew = false
        }
    },
    mounted(){
        bus.$on(`xin`, function () {    //接收到伺服器端有新資料,那我就提示有新資料樓
            this.isHasNew = true
        }.bind(this))
    }
    ...
}

相關文章