天天看點

socket.io建立聊天系統

<>線上聊天系統<>

[service]

var express = require('express');
var app = express();
var http = require('http').Server(app);
var io = require('socket.io')(http);

app.get('/', function (req, res) {
  res.sendFile(__dirname + '/socket_cli.html');
});

var onlineUserCount = 0; //用戶端連接配接數量
var onlineUsers = {}; //統計用戶端登入使用者

io.on('connection', function (socket) {
  socket.emit('open');  //通知用戶端已連接配接

  //構造用戶端對象
  var client = {
    socket: socket,
    name: false
  }

  //監聽用戶端的chat message事件, 該事件由用戶端觸發
  //當服務端收到消息後,再把該消息播放出去,繼續觸發chat message事件, 然後在用戶端監聽chat message事件。
  socket.on('chat message', function (msg) {
    console.log('chat message:' + msg);
    var obj = { time: getTime() }; //建構用戶端傳回的對象

    //判斷是不是第一次連接配接,以第一條消息作為昵稱
    if (!client.name) {
      onlineUserCount++;

      client.name = msg;
      obj['text'] = client.name;
      obj['author'] = 'Sys';
      obj['type'] = 'welcome';
      obj['onlineUserCount'] = onlineUserCount;
      socket.name = client.name; //使用者登入後設定socket.name, 當退出時用該辨別删除該線上使用者
      if (!onlineUsers.hasOwnProperty(client.name)) {
        onlineUsers[client.name] = client.name;
      }
      obj['onlineUsers'] = onlineUsers; //目前線上使用者集合
      console.log(client.name + ' login,目前線上人數:' + onlineUserCount);

      //傳回歡迎語
      socket.emit('system', obj);  //發送給自己的消息
      //廣播新使用者已登入
      socket.broadcast.emit('system', obj); //向其他使用者發送消息
    } else {
      //如果不是第一次聊天,則傳回正常的聊天消息
      obj['text'] = msg;
      obj['author'] = client.name;
      obj['type'] = 'message';
      console.log(client.name + ' say:' + msg);

      socket.emit('chat message', obj); //發送給自己的消息 , 如果不想列印自己發送的消息,則注釋掉該句。
      socket.broadcast.emit('chat message', obj); //向其他使用者發送消息

    }
    //io.emit('chat message',msg);
  });

  socket.on('disconnect', function () {
    onlineUserCount--;

    if (onlineUsers.hasOwnProperty(socket.name)) {
      delete onlineUsers[client.name];
    }

    var obj = {
      time: getTime(),
      author: 'Sys',
      text: client.name,
      type: 'disconnect',
      onlineUserCount: onlineUserCount,
      onlineUsers: onlineUsers
    };

    //廣播使用者退出
    socket.broadcast.emit('system', obj); //使用者登入和退出都使用system事件播報
    console.log(client.name + ' disconnect,目前線上人數:' + onlineUserCount);
  });


});

http.listen(3000, function () {
  console.log('server begin...');
});

var getTime = function () {
  var date = new Date();
  return date.getHours() + ":" + date.getMinutes() + ":" + date.getSeconds();
}

var getColor = function () {
  var colors = ['aliceblue', 'antiquewhite', 'aqua', 'aquamarine', 'pink', 'red', 'green',
    'orange', 'blue', 'blueviolet', 'brown', 'burlywood', 'cadetblue'];
  return colors[Math.round(Math.random() * 10000 % colors.length)];
}
           

[client]

<!doctype html>
<html>

<head>
  <title>Socket.IO chat</title>
  <style>
    * {
      margin: 0;
      padding: 0;
      box-sizing: border-box;
    }

    body {
      font: 13px Helvetica, Arial;
    }

    div {
      background: #000;
      padding: 3px;
      position: fixed;
      bottom: 0;
      width: 100%;
    }

    div input {
      border: 0;
      padding: 10px;
      width: 90%;
      margin-right: .5%;
    }

    div button {
      width: 9%;
      background: rgb(130, 224, 255);
      border: none;
      padding: 10px;
    }

    #messages {
      list-style-type: none;
      margin: 0;
      padding: 0;
    }

    #messages li {
      padding: 5px 10px;
    }

    #messages li:nth-child(odd) {
      background: #eee;
    }

    p {
      padding: 5px 10px;
    }
  </style>
</head>

<body>
  <p id="onlineUser">線上人數:0</p>
  <ul id="messages"></ul>

  <div action="">
    <input id="m" autocomplete="off" />
    <button>Send</button>
  </div>
  <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.0.3/socket.io.js"></script>
  <script src="http://code.jquery.com/jquery-1.11.1.js"></script>
  <script type="text/javascript">
    var myName = false;

    var socket = io('http:/localhost:3000');
    socket.on('open', function () {
      $('#messages').append($('<li>').text('已連接配接至伺服器,請輸入昵稱'));
    });

    //監聽system事件,判斷welcome或者disconnect,列印系統消息
    socket.on('system', function (json) {
      var sep = '';
      var onlinehtml = '';
      var onlineUsers = json.onlineUsers;
      for (key in onlineUsers) {
        if (onlineUsers.hasOwnProperty(key)) {
          onlinehtml += sep + onlineUsers[key];
          sep = '、';
        }
      }

      if (json.type === 'welcome') {
        $('#messages').append($('<li>').text('Sys(' + json.time + ')welcome ' + json.text));
        $('#onlineUser').text('線上人數:' + json.onlineUserCount + '。線上清單:' + onlinehtml);
      } else if (json.type === 'disconnect') {
        $('#messages').append($('<li>').text('Sys(' + json.time + ')bye ' + json.text + ''));
        $('#onlineUser').text('線上人數:' + json.onlineUserCount + '。線上清單:' + onlinehtml);
      }
    });

    //監聽服務端的chat message事件,接受每一條消息
    socket.on('chat message', function (json) {
      $('#messages').append($('<li>').text(json.author + '(' + json.time + ')' + ':' + json.text));
    });


    $('#m').keydown(function (e) {
      if (e.keyCode === 13) {
        socket.emit('chat message', $('#m').val());

        //socket.send($('#m').val());
        $('#m').val('');
        if (myName === false) {
          myName = $('#m').val();
        }
      }
    })
  </script>
</body>

</html>
           

參考文檔:https://socket.io/