[node. js] Private chat based on Socket.io

Source: Internet
Author: User
Tags emit event listener

Original address: http://www.moye.me/2015/01/02/node_socket-io/

Introduction

Recently heard a question: Socket.io How to achieve private chat? In other words: How to locate the person (end), or how to identify the connection, rather than rely on the socket.id of each connection. Good question.

Under the guidance of Socket.io real-time WEB application development, the following ideas are formed:

    1. The server generates SESSION_ID when each user enters the system for the first time
    2. Service-side force user to enter nickname, corresponding to session_id
    3. The Socket.io of the server can be obtained when connected, socket.request.headers.cookie parse out the session_id from this cookie, and correspond the socket connection to the session_id in the context of the web framework.
    4. Use an array on the server to hold the corresponding relationships that are generated by the above three:[{name, session_id, socket} , ...]
    5. With an array of correspondence, you can locate people and distinguish [me] from [others], and you can use a saved socket for private chats.

With the idea, you can practice it:

Server Side

ES6 generator is too good to use, do Node Web start from KOA. Well, my package.json seems to have these dependent libraries:

"Co": "^4.0",        "KOA": "^0.14.0", "Koa-mount": "*",  "Koa-ejs": "*"," Koa-static ":" * "," Koa-router ":" * "," koa-session ":" * "," co-body ":" * "
User List

The list of users mentioned in the idea is a simple array: The [{name, session_id, socket} , ...] operation around it is also very simple (Sockethandler:

//interfaces exposed to the WebModule.exports.addUser =AddUser; Module.exports.otherUsers=otherusers;varUsers = [];functionFindinusers (session_id) {//Find by session_id    varindex =-1;  for(varj = 0, len = users.length; J < Len; J + +) {        if(users[j].session_id = = =session_id) Index=J; }    returnindex;}functionaddUser (name, session_id) {varindex =findinusers (session_id); if(Index = = =-1)//does not exist then add againUsers.push ({name:name, session_id:session_id, Socket:NULL}); Else{//Update only Nicknames        if(Users[index].name!==name) Users[index].name=name; }}functionSetusersocket (session_id, socket) {//Update user Socket    varindex =findinusers (session_id); if(Index!==-1) {Users[index].socket=socket; }}functionFinduser (session_id) {varindex =findinusers (session_id); returnIndex >-1? Users[index]:NULL;}functionOtherusers (session_id) {//Other People    varResults = [];  for(varj = 0, len = users.length; J < Len; J + +) {        if(users[j].session_id!==session_id) Results.push ({session_id:users[j].session_id, name:users[j].name}); }    returnresults;}
Session Store

Koa-session This library provides session storage functionality, which is very simple to use:

var koa = require (' KOA '); var session = require (' koa-session '); var app == [CONFIG. Secret];app.use (session (APP));

In addition, Koa-session will enclose a session_id identity string in the cookie for Web request, koa:sess so we can use it in the event listener for Socket.io:

function (socket) {    var sessionId = GetSessionID (socket.request.headers.cookie,         ' KOA: Sess ');     if (sessionId) {         setusersocket (sessionId, socket);     }); function GetSessionID (cookiestring, cookiename) {    varnew RegExp (cookiename +          ' = ( [^;] +); ', ' Gmi '). EXEC (cookiestring);     return NULL ;}
User Login

The so-called login, is to let the user enter a nickname, and it corresponds to the session_id, and stored in the above user array. Assuming our routing path is/chat and the login action path is/chat/login, the route looks like this:

varRouter = require (' Koa-router ')), Router=NewRouter ();varParse = require (' Co-body ');varSockethandler = require ('.. /.. /middlewares/sockethandler ');//Get/chatRouter.get ('/',function*() {    varsession_id = This. Cookies.get (' koa:sess '); varName = This. Session.name; if(session_id && name) {//Add to User listsockethandler.adduser (name, session_id); Yield This. Render ('.. /www/views/chat ');//using Ejs}Else {         This. Redirect ('/chat/login '); }});//get/chat/login using Ejs templatesRouter.get ('/login ',function*() {yield This. Render ('.. /www/views/login ')});//Post/chat/login Receive form submission: <input name= ' name ' >Router.post ('/login ',function*(){    varBODY = Yield Parse ( This);  This. Session.name = Body.name | | ' Guest ';  This. Redirect ('/chat ')}); Module.exports= Router;
Broadcast and private chat message processing
Io.on (' Connection ',function(socket) {Socket.on (' Broadcast ',function(data) {//Broadcast        varFromuser =Finduser (sessionId); if(Fromuser) {Socket.broadcast.emit (' Broadcast ', {name:fromUser.name, msg:data.msg});        }    }); Socket.on (' Private ',function(data) {//private Chat {to_session_id, msg}        varFromuser =Finduser (sessionId); if(fromuser) {varTouser =Finduser (data.to_session_id); if(Touser) toUser.socket.emit (' Private ', {name:fromUser.name, msg:data.msg}); }    });});
Client

After connecting to the server, the client will periodically pull the list of others:

// get a list of other people regularly function updateothers () {    $.post(function  (others) {         //... Some ugly UI DOM manipulation code         setTimeout (updateothers, +);     1000);

Corresponding, the server will have one such interface:

//post/chat/others Other People listRouter.post ('/others ',function*(){    varsession_id = This. Cookies.get (' koa:sess '); varName = This. Session.name; if(session_id &&name) {         This. Type = ' Application/json ';  This. BODY =sockethandler.otherusers (session_id); } Else {         This. Status = 404; }});
Run effect

Run in three different browsers like a chat room that didn't fire in the late 90:)

Source

Complete source stacking on my github: Https://github.com/rockdragon/socketchat, to get it running, you need to get Node up to 0.11.14 (because of the Co V4), of course, the README. The MD has detailed setup instructions.

More articles please visit my blog new address: http://www.moye.me/

[node. js] Private chat based on Socket.io

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.