zoukankan      html  css  js  c++  java
  • nodejs实如今线群聊


    这不是一个项目而是一个适合刚開始学习的人学习的样例。主要实现了下面基本功能:

    1:群聊。每个人都能够收到其它人的消息,以及能够发消息给其它人,每个人用ip地址标识。

    2:显示当前在线用户。

    3:每个用户登入登出。其它人都能够看到。

    4:每个用户能够看到其它人是否正在输入消息。


    实现方式没有选择低效的轮询方式,而是採用基于websocket协议的socket.io模块,websocket协议同意在client与服务端之间建立一个全双工的通信通道。因此服务端能够主动推消息给client。相比传统的轮询,实时性更好。

    前端代码例如以下:

    <!doctype html>
    <html>
    <head>
        <title>Socket.IO chat</title>
        <style>
            * { margin: 0; padding: 0; box-sizing: border-box; }
            body { font: 13px Helvetica, Arial; }
            form { background: #fc5bff; padding: 2px; position: fixed; bottom: 0;  100%; }
            form input { border: 0; padding: 10px;  90%; margin-right: .5%; }
            form button {  9%; background: rgb(217, 222, 221); 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; }
        </style>
    </head>
    <body>
    <ul id="messages"></ul>
    <ul><li id='typingshow'></li></ul>
    <div id='joinshow'></div>
    <div id='leftshow'></div>
    <div id='onlineshow'></div>
    <form action="">
    
        <input id="m" autocomplete="off" /><button id='btn'>Send</button>
    </form>
    <script src="jquery-1.10.2.min.js"></script>
    <script src="/socket.io/socket.io.js"></script>
    <script>
        var socket = io();
        var typingIps={};
        var typing=false;
        var lastTypingTime;
        function updateTyping() {
            if (!typing) {
                typing = true;
                socket.emit('typing');
            }
            lastTypingTime = (new Date()).getTime();
    
            setTimeout(function () {
                var typingTimer = (new Date()).getTime();
                var timeDiff = typingTimer - lastTypingTime;
                if (timeDiff >= 400 && typing) {
                    socket.emit('stop typing');
                    typing = false;
                }
            }, 400);
        }
        $('form').submit(function(){
            socket.emit('chat message',$('#m').val());
            socket.emit('stop typing');
            typing = false;
            $('#m').val('');
            return false;
        });
        $('#m').keyup(function(){
            updateTyping();
        });
        socket.on('online num',function(msg){
            $('#onlineshow').text('当前在线'+msg+'人');
        });
    
        socket.on('join', function (msg) {
            $('#joinshow').text(msg.ip+'增加');
        });
        socket.on('typing',function(msg){
            typingIps[msg.ip]=msg.ip;
            var typingArr=[];
            for(var ip in typingIps){
                typingArr.push(typingIps[ip]);
            }
            $('#typingshow').text(typingArr.join(',') + '正在输入...');
        });
        socket.on('stop typing',function(msg){
            delete typingIps[msg.ip];
            var typingArr=[];
            for(var ip in typingIps){
                typingArr.push(typingIps[ip]);
            }
            if(typingArr.length===0){
                $('#typingshow').text('');
            }else{
                $('#typingshow').text(typingArr.join(',') + '正在输入...');
            }
        });
        socket.on('chat message', function(msg){
            $('#messages').append($('<li>').text(msg.ip+'说:'+msg.content));
        });
        socket.on('user left', function(msg){
            $('#leftshow').text(msg.ip+'离开了');
            $('#onlineshow').text('当前在线'+msg.onlineNum+'人');
        });
    </script>
    </body>
    </html>

    服务端代码:

    /**
     * Created by luzhen on 14-11-10.
     */
    var express = require('express');
    var app=express();
    var http = require('http').Server(app);
    var io = require('socket.io')(http);
    var ips={};
    app.use(express.static(__dirname + '/public'));
    app.get('/', function (req, res) {
        res.sendFile(__dirname + '/index.html');
    });
    var onlineNum=0;
    io.on('connection', function (socket) {
        console.log(socket.request.connection.remoteAddress);
        ips[socket.request.connection.remoteAddress]=socket.request.connection.remoteAddress;//clientip
        //socket.handshake.address 服务端ip
        onlineNum++;
        socket.broadcast.emit('join', {'ip':socket.request.connection.remoteAddress});//广播新用户增加
    
        io.emit('online num',onlineNum);//广播当前在线人数
    
        socket.on('chat message', function (msg) {
            io.emit('chat message', {ip:socket.request.connection.remoteAddress,'content':msg});
            console.log('message: ' + msg);
        });
    
        socket.on('typing', function (msg) {
            socket.broadcast.emit('typing', {'ip':socket.request.connection.remoteAddress});
        });
        socket.on('stop typing', function (msg) {
            socket.broadcast.emit('stop typing', {'ip':socket.request.connection.remoteAddress});
        });
    
        socket.on('disconnect',function(){
            delete ips[socket.request.connection.remoteAddress];
            onlineNum--;
            socket.broadcast.emit('user left', {'ip':socket.request.connection.remoteAddress,'onlineNum':onlineNum});
        });
    });
    
    http.listen(3000, function () {
        console.log('listening on *:3000');
    });

    新增了防止刷屏功能,完整代码开源在GitHub上。

    Demo演示 查看效果


  • 相关阅读:
    Java访问Oracle服务器
    easyUI之练习
    easyUI之Tree(树)
    easyUI之Messager(消息窗口)
    easyUI之表单
    easyUI之Dialog(对话框窗口)
    easyUI之函数
    easyUI之window窗口
    easyUI之progressbar进度条
    easyUI之slider滑动条框
  • 原文地址:https://www.cnblogs.com/tlnshuju/p/7172356.html
Copyright © 2011-2022 走看看