1. 程式人生 > >html5 websocket + node.js 實現網頁聊天室

html5 websocket + node.js 實現網頁聊天室

1 client:    socket.io

   server:   node.js +  express  + socket.io  

一個簡單的聊天室  demo,沒有註冊,內建了一些測試使用者

2 client 關鍵程式碼

複製程式碼

var socket = io.connect('http://localhost:8080');    
socket.on('connect',function(){
    console.log('connected to server');    
    socket.on('login success',function(data){
        console.log('login success');
        username = data.username;
            
        refreshOnlineUsers(data.allusers);
    });
        
    socket.on('disconnect',function(){
        console.log('disconnect');
        username = null;    
    });
    
    socket.on('login failed',function(){
        username = null;    
    });
    
    socket.on('new message',function(data){
        console.log('receiver message from '+data.fromUser +' '+data.date+ ' '+data.msg);
    });
        
    socket.on('update myself',function(data){
    });
    
    socket.on('enter chat',function(data){
        console.log(data.username+' has entered the chat');
        refreshOnlineUsers(data.allusers);
    });
    
    socket.on('leave chat',function(data){
        console.log(data.username + ' has leaved the chat');
        refreshOnlineUsers(data.allusers);
    });
});

複製程式碼

3 server 關鍵程式碼

複製程式碼

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

app.use('/', express.static(__dirname + '/www'));
 
var users = {
    fanglin:{
        socket:null,
        online:false
    },
    xingtianyu:{
        socket:null,
        online:false
    }
};

io.on('connection', function(socket){
    socket.on('new message',function(data){
        var i,user;
        
        socket.emit('update myself',{fromUser:data.fromUser,msg:data.msg,date:new Date()});
        
        if(data.broadcast===true){
            socket.broadcast.emit('new message',{fromUser:data.fromUser,msg:data.msg,date:new Date()});
        }else{
            for(i=0;i<data.tousers.length;i++){
                user = users[data.tousers[i]];
                if(user.online==true && user.socket!=null){
                    user.socket.emit('new message',{fromUser:data.fromUser,msg:data.msg,date:new Date()});
                }
            }
        }
    });
    
    socket.on('login',function(data){
        if(data.username in users){
            users[data.username].online = true;
            users[data.username].socket = socket;
            socket.emit('login success',{username:data.username,allusers:getOnlineUsers()});
            socket.broadcast.emit('enter chat',{username:data.username,allusers:getOnlineUsers()});
        }else{
            socket.emit('login failed');
        }
    });
    
    socket.on('disconnect',function(){
        var user;
        for (user in users){
            if(users[user].socket == socket){
                users[user].online = false;
                socket.broadcast.emit('leave chat',{username:user,allusers:getOnlineUsers()});
                return;
            }
        }
    });
});

server.listen(8080);
console.log('server is listenering on port 8080');

複製程式碼

4 實現了一個簡單的有限狀態機

(1) 客戶端啟動時去連線伺服器,連線成功觸發服務端的 connection 事件

(2) 連線成功後客戶端可登陸,觸發服務端的 login 事件,服務端查詢使用者,若登陸成功服務端向客戶端傳送 login success 的訊息,並返回所有線上使用者,同時向其他線上使用者傳送 enter chat 廣播,登陸失敗則向客戶端傳送 login failed 訊息。

(3) 客戶端登陸成功後可向其他線上使用者傳送訊息,客戶端向服務端傳送 new message 訊息,服務端收到  new message  訊息後,先向客戶端傳送  update myself 訊息,客戶端如果勾選了 Select All, 服務端會接著傳送 new message 廣播,否則遍歷所有接收者,依次向這些接收者傳送 new message 訊息。

(4) 客戶端斷開連線後觸發服務端 disconnect 事件,服務端傳送 leave chat 廣播。

(5) 客戶端在收到 new message  update myself 時會更新聊天室裡的聊天內容。收到 login success 、 enter chat  、leave chat 時會更新當前線上使用者。收到 login success 、login failed 時更新線上狀態 。。。

 

程式碼不多非常簡單,大家一看就能明白.

程式碼地址: https://github.com/lesliebeijing/MyChatRoom.git