1. 程式人生 > 實用技巧 >websocket原生開發聊天室

websocket原生開發聊天室

websocket原生開發聊天室

chat.html
<!DOCTYPE html>
<html lang='en'>
  <head>
    <meta charset='UTF-8'/>
    <meta name="viewport" content = "width=divice-width,initial-scale=1.0"/>
    <title>Socket.IO chat</title>
    <style>
      /* div{
        width:800px;
        height:500px;
        background-color: bisque;
        border: darkkhaki;
      } */
      button { width: 9%; background: darksalmon; border: none; padding: 10px; }
    </style>  
  </head>
  <body>
    <input type = 'text' placeholder="請輸入你的內容" />
    <button>Send</button>
    <div></div>
  </body>
</html>

<script>
  const TYPE_ENTER = 0
  const TYPE_LEAVE = 1
  const TYPE_MSG = 2
  var div = document.querySelector('div')
  var button = document.querySelector('button')
  var input = document.querySelector('input')
  //有了自己的server,就可以連線自己的server   ws://echo.websocket.org
    var socket = new WebSocket('ws://localhost:3000');
    socket.addEventListener('open',function(){
      div.innerHTML = '連線成功'
    })
    button.addEventListener('click',function(){
      var value = input.value;
      socket.send(value)
      input.value=''
    })
    socket.addEventListener('message',function(e){
      var data = JSON.parse(e.data)
      console.log(e.data)
      //div.innerHTML = e.data
      var dv = document.createElement('div')
      dv.innerText = data.msg + '---' +data.time
      if(data.type === TYPE_ENTER){
        dv.style.color = 'green'
      }else if(data.type === TYPE_LEAVE){
        dv.style.color = 'red'
      }else{
        dv.style.color = 'blue'
      }
      div.appendChild(dv)
    })
    socket.addEventListener('close',function(){
      div.innerHTML = '服務斷開連線'
    })
  </script>
server.js
//匯入node.js-websocket
const ws = require('nodejs-websocket')
const PORT = 3000
let count = 0  //連線上來的總的使用者數量
const TYPE_ENTER = 0
const TYPE_LEAVE = 1
const TYPE_MSG = 2
//建立一個server
//每次有使用者連線,函式就會被執行,就會給使用者創造一個連線物件conn 
//每個使用者都有一個conn
/*
為了讓訊息有格式,顏色這樣,需要廣播一個物件,
有type: 0--使用者進入   1--使用者離開   2--正常訊息
*/
const server = ws.createServer(conn => {
  console.log("an user connected.")
  count ++
  conn.username = `使用者${count}`
  //告訴所有使用者,有人加入了聊天室
  //broadcast(`${conn.username}進入了聊天室`)
  broadcast({
    type:TYPE_ENTER,
    msg:`${conn.username}進入了聊天室`,
    time:new Date().toLocaleTimeString()
  })
  conn.on('text',data => {
    //我個人感覺,這個server.js就是自己實現那個url實現的功能
    console.log("接收到了使用者的資料",data)
    //conn.send(data)   //send只能給此使用者傳送
    //connect.send(data.toUpperCase()+"!!!")
    //broadcast(data)
    broadcast({
      type:TYPE_MSG,
      msg:data,
      time:new Date().toLocaleTimeString()
    })
  })

conn.on('close',() => {
  console.log("連線斷開了")
  count --
  //broadcast(`${conn.username}離開了聊天室`)
  broadcast({
    type:TYPE_LEAVE,
    msg:`${conn.username}離開了聊天室`,
    time:new Date().toLocaleTimeString()
  })
})
conn.on('error',() => {
  console.log("使用者連線異常")
})



})


//廣播 給所有的使用者傳送訊息
function broadcast(msg){
  //server.connections表示所有使用者
  server.connections.forEach(item => {
    //send:只允許傳字串,現在要傳的訊息為一個物件,所以需要先轉化為字串
    item.send(JSON.stringify(msg))
  })
}


server.listen(PORT,() => {
  console.log('websocket啟動成功')
})