nodejs即时通讯模块+SocketIO4Net的使用小结

实现思路:客户端js连接了nodejs服务,通过.net连接nodejs服务,通过.net发送消息到nodejs,然后通过nodejs将消息推送给(用户)客户端

1、先下载nodejs安装,至于怎么安装nodejs网上很多说明,这里就不做说明了

2、下载SocketIO4Net

SocketIO4Net开源项目结构如下:

进入项目的目录:socketio4net-developsamples ode.server 如图下图:

双击先 install.cmd运行这个文件安装nodejs需要的模块(这个步骤需要在已经连接网络下进行),在双击运行startServer.cmd文件启动nodejs服务,服务启动成功入下图:

使用nodejs可以快速搭建一个即时通讯的聊天室下载请点这里

使用下载SocketIO4Net开源类库可以快速链接nodejs通讯服务进行交互通讯

SocketIO4Net的项目里面有个控制台Console_Events项目下有个EventClient.cs类,进行二次开发主要参照这个类的写法去开发,加入自己的逻辑

我做测试修改的EventClient.cs类的代码如下:

using System;
using System.Diagnostics;
using System.Threading;
using SocketIOClient;
using Newtonsoft.Json.Linq;
using System.Linq;
using System.Text.RegularExpressions;
using SocketIOClient.Messages;
using System.Net;

namespace ConsoleEvents
{
    /// <summary>
    /// Example usage class for SocketIO4Net
    /// </summary>
    public class EventClient
    {
        Client socket;
        public void Execute()
        {
            Console.WriteLine("Starting SocketIO4Net Client Events Example...");

            socket = new Client("http://127.0.0.1:3000/")
            {
            }; // url to the nodejs / socket.io instance
            //socket.TransportPeferenceTypes.Add(TransportType.XhrPolling);
            socket.Opened += SocketOpened;
            socket.Message += SocketMessage;
            socket.SocketConnectionClosed += SocketConnectionClosed;
            socket.Error += SocketError;

            // Optional to add HandShake headers - comment out if you do not have use
            socket.HandShake.Headers.Add("OrganizationId", "1034");
            socket.HandShake.Headers.Add("UserId", "TestSample");
            socket.HandShake.Headers.Add("Cookie", "somekookie=magicValue");
            socket.HandShake.Headers.Add("token", "Fxt_ABCDEFGHIJKLMNOPQRSTUVWXYZ");

            // Register for all On Events published from the server - prior to connecting

            // register for 'connect' event with io server
            socket.On("connect", (fn) =>
            {
                Console.WriteLine("
Connected event...{0}
", socket.ioTransport.TransportType);
                socket.Emit("subscribe", new { room = "eventRoom" }); // client joins 'eventRoom' on server
            });


            // register for 'update' events - message is a json 'Part' object
            socket.On("update", (data) =>
            {
                Console.WriteLine("recv [socket].[update] event");
                Console.WriteLine("  raw message:      {0}", data.RawMessage);
                Console.WriteLine("  string message:   {0}", data.MessageText);
                Console.WriteLine("  json data string: {0}", data.Json.ToJsonString());
                // cast message as Part - use type cast helper
                Part part = data.Json.GetArgAs<Part>();
                Console.WriteLine(" PartNumber:   {0}
", part.PartNumber);
            });

            // register for 'alerts' events - broadcast only to clients joined to 'Room1'
            socket.On("log", (data) =>
            {
                Console.WriteLine(" log: {0}", data.Json.ToJsonString());
            });
            socket.On("empty", (data) =>
            {
                Console.WriteLine(" message 'empty'");
            });
            //socket.Connect(SocketIOClient.TransportType.XhrPolling);
            socket.Connect();
        }

        public void SendMessageSamples()
        {

            // random examples of different styles of sending / recv payloads - will add to...
            //socket.Send(new TextMessage("Hello from C# !")); // send plain string message
            //socket.Emit("hello", new { msg = "My name is SocketIO4Net.Client!" }); // event w/string payload
            //socket.Emit("sendtodepartment", new { token = "Fxt_ABCDEFGHIJKLMNOPQRSTUVWXYZ", todepartmentids = "user_123_123,user_1234_1234,user_12345_12345", msg = "eeeeeeeeeeeeeeeeeeeeee" });
           // socket.Emit("sendtousers", new { token = "Fxt_ABCDEFGHIJKLMNOPQRSTUVWXYZ", touserids = "user_123w_123q,user_1234_1234,user_12345_12345", msg = "xxxxxxxxxxxxxxxxxxxxxxxxx" });
            socket.Emit("sendMsg", new { token = "qfefefedfwrfwefw4teryurtyewtwerwererererwe", UserId = "1", UserName = "test", msg = "xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" });
            //socket.Emit("heartbeat"); // event w/o data payload (nothing to do with socket.io heartbeat)
            
            //socket.Emit("hello", "simple string msg");
            //socket.Emit("partInfo", new { PartNumber = "AT80601000741AA", Code = "SLBEJ", Level = 1 }); // event w/json payload

            //Part newPart = new Part() { PartNumber = "K4P2G324EC", Code = "DDR2", Level = 1 };
            //socket.Emit("partInfo", newPart); // event w/json payload


            // callback using namespace example 
            //Console.WriteLine("Emit [socket.logger].[messageAck] - should recv callback [socket::logger].[messageAck]");
            //socket.Emit("messageAck", new { hello = "papa" }, "",
            //    (callback) =>
            //    {
            //        var jsonMsg = callback as JsonEncodedEventMessage; // callback will be of type JsonEncodedEventMessage, cast for intellisense
            //        Console.WriteLine(string.Format("callback [socket::logger].[messageAck]: {0} 
", jsonMsg.ToJsonString()));
            //    });
        }

        void SocketError(object sender, ErrorEventArgs e)
        {
            Console.WriteLine("socket client error:");
            Console.WriteLine(e.Message);
        }

        void SocketConnectionClosed(object sender, EventArgs e)
        {
            Console.WriteLine("WebSocketConnection was terminated!");
        }

        void SocketMessage(object sender, MessageEventArgs e)
        {
            // uncomment to show any non-registered messages
            if (string.IsNullOrEmpty(e.Message.Event))
                Console.WriteLine("Generic SocketMessage: {0}", e.Message.MessageText);
            else
                Console.WriteLine("Generic SocketMessage: {0} : {1}", e.Message.Event, e.Message.JsonEncodedMessage.ToJsonString());
        }

        void SocketOpened(object sender, EventArgs e)
        {

        }

        public void Close()
        {
            if (this.socket != null)
            {
                socket.Opened -= SocketOpened;
                socket.Message -= SocketMessage;
                socket.SocketConnectionClosed -= SocketConnectionClosed;
                socket.Error -= SocketError;
                this.socket.Dispose(); // close & dispose of socket client
            }
        }
    }

}
View Code

修改server.js测试代码如下

process.env['DEBUG'] = 'server:*';
var config = require('./config.json'),
    debug = {
        io: require('debug')('server:io'),
        app: require('debug')('server:app'),
        server: require('debug')('server:server'),
        config: require('debug')('server:config'),
        error: require('debug')('server:error')
    },

    http = require('http'),
    express = require('express'),
    app = express(),
    util = require('util'),
    socketio = require('socket.io'),
    socketioWildcard = require('socket.io-wildcard'),
    server,
    io,
    userArray = [],
    token = "qfefefedfwrfwefw4teryurtyewtwerwererererwe";

//server = http.createServer(app),
//io = socketio.listen(server),
webApi = require('./routes/api'),
store = require('./store'); // cheap key-value stand-in for redis

// Splash Info
debug.config('');
debug.config('SocketIO4Net Sample Server
');
debug.config('	Nodejs: %s', process.version);
debug.config('	socket.io: v%s', socketio.version);
debug.config('	Listening on port %d', config.web.port);
debug.config('');

// *******************************
// Configure Express
// *******************************
app.configure('development', function () { // only in development
    app.use(logErrors);
});

app.configure(function () {
    app.use(express.favicon());
    app.use(express.bodyParser());
    app.use(express.compress());
    app.use(express.methodOverride());
    app.use(errorHandler);

    // serve static assets from these folder
    app.use('/scripts', express.static('scripts'));
    app.use('/content', express.static('content'));
    app.use('/app', express.static('app'));


    // basic usage logging
    app.use(function (req, res, next) {
        // console.log('%s %s', req.method, req.url);
        if (req.url.indexOf('/api') === 0) {
            store.incr('app.apiCount');
        }
        //watchBcast('log', { level: 5, zone: 'app', eventCode: 'request', message: 'url', data: { 'method': req.method, 'url': req.url, 'count': cnt } });
        next();
    });

});

//var socketio1 = io.listen(server);
server = http.createServer(app).listen(config.web.port);
//io = socketio.listen(server);
io = socketioWildcard(socketio).listen(server);

// General Handlers
app.get('/api/:target', webApi.get);
app.get('/config', function (req, res) {
    res.send(config.clientConfiguration);
});
app.get('/', function (req, res) {
    store.incr('app.visits');
    res.sendfile(__dirname + '/index.html');
    watchBcastAnalytics();
});

// *******************************
// Configure socket.io
// *******************************
io.enable('browser client minification');  // send minified client
io.enable('browser client etag');          // apply etag caching logic based on version number
io.enable('browser client gzip');          // gzip the file
io.set('log level', 1);                    // reduce logging: 0-error, 1-warn, 2-info, 3-debug
io.set('transports', ['websocket', 'xhr-polling', 'jsonp-polling', 'htmlfile']);

// *******************************
// socket.io handlers
// *******************************
io.sockets.on('connection', function (socket) { // initial connection from a client
    var transport = io.transports[socket.id].name,
        key = transport === 'websocket' ? 'websocket' : 'other';

    store.incr('io.connection.' + key);
    debug.io('client connection: %s', transport);
    watchBcastAnalytics();
    watchBcast('log', { zone: 'io', eventCode: 'connection', message: 'connection' }); // bcast connection count to 'watch' room
    watchBcast('log', { zone: 'server', eventCode: 'api', message: webApi.statusCounts() });
    socket.on('*', function onWildcard(event) {
        watchBcast('log', { zone: 'io', eventCode: event.name || '?', message: util.inspect(event) });
    });
    socket.on('message', function (data) {
        watchBcast('log', { zone: 'client', eventCode: 'message', message: data });
    });

    socket.on('echo', function (message) {
        socket.emit('echo', message);
    });
    socket.emit('news', { hello: 'world' });

    socket.on('clientBroadcast', function (message) {
        var combinedMsg;
        try {
            if (message.room) {
                combinedMsg = [message.room, message.event];
                socket.broadcast.to(message.room).emit(message.event, message.data); //emit to 'room' except this socket
            } else {
                combinedMsg = [message.event];
                socket.broadcast.emit(message.event, message.data); //emit to all sockets except this one
            }
            //watchBcast('log', { zone: 'clientBroadcast', eventCode: combinedMsg, message: message.data });
        } catch (err) {
            debug.io('clientBroadcast error', message, err);
            store.incr('io.errors');
            watchBcastAnalytics();
        }
    });
    // client request to join 'room' data.room by name
    socket.on('subscribe', function (event) {
        socket.join(event.room);
        if (event.room === 'watch') {
            socket.emit('analytics', webApi.statusCounts());
        }
    });
    // client request to leave 'room' data.room by name
    socket.on('unsubscribe', function (event) { socket.leave(event.room); });

    socket.on('disconnect', function () { // client-server connection is closed
        store.decr('io.connection.' + key);
        watchBcastAnalytics();
        watchBcast('log', { zone: 'io', eventCode: 'disconnect', message: 'client' });

        for (var loop = 0; loop < userArray.length; loop++) {
            if (userArray[loop].SocketId == socket.id) {
                userArray.splice(loop, 1);
                console.log("disconnect", "client-server connection is closed");
                //delete users[loop];
                break;
            }
        }
    });

    socket.on('userLogin', function (paraData) {  //用户登录(客户端与服务端(nodejs)服务连接入口) , paraData 是客户登录时传过来的数据一个js对象
        var user = {};
        user.SocketId = socket.id;
        user.UserId = paraData.UserId;
        user.UserName = paraData.UserName;
        user.Socket = socket;
        userArray.push(user);  //添加用户的登录
        console.log('用户登录成功: ', user);
    });

    socket.on('sendMsg', function (data) {  //发送消息给用户 data是通过(,net)后端发送过来的数据,经过此事件推送到客户端(用户)
        console.log('sendMsg: ', data);
        if (data.token == token) {
            if (data.UserId != "0") { //推送给单个用户
                for (var i = 0; i < userArray.length; i++) {
                    if (userArray[i].UserId == data.UserId) {
                        userArray[i].Socket.emit('message', data); //将消息推送到客户端
                        break;
                    }
                }
            } else {  //推送给全部用户
                for (var j = 0; j < userArray.length; j++) {
                    userArray[j].Socket.emit('message', data); //将消息推送到客户端
                }
            }
        } else {
            console.log('token Error!');
        }
    });
});

// *******************************
// Error Logging / broadcast helpers
// *******************************
function watchBcast(event, data) {
    try {
        data.dateTime = new Date(Date.now());
        io.sockets.in('watch').emit(event, data);
        debug.io(util.inspect(data));
    } catch (err) {
        debug.error('watchBcast error: %s', err);
        store.incr('io.errors');
    }
}
function watchBcastAnalytics() {
    watchBcast('analytics', webApi.statusCounts());
}

function logErrors(err, req, res, next) {
    store.incr('app:errors');
    var status = err.statusCode || 500;
    debug.io(status + ' ' + (err.message ? err.message : err));
    if (err.stack) {
        debug.error(err.stack);
    }
    watchBcastAnalytics();
    next(err);
}

function errorHandler(err, req, res, next) {
    var status = err.statusCode || 500;
    if (err.message) {
        res.send(status, err.message);
    } else {
        res.send(status, err);
    }
    watchBcastAnalytics();
}

process.on('uncaughtException', function (err) {
    // handle the error safely
    debug.error(err);
    store.incr('app:errors');
    watchBcastAnalytics();
});
View Code

客户端代码:

<!DOCTYPE html>
<html>
<body>
    <h1>WebSocket</h1>
    <script src="http://127.0.0.1:3000/socket.io/socket.io.js"></script>
    <script type="text/javascript">

        window.onload = (function () {
            var iosocket = io.connect("ws://127.0.0.1:3000/");
            iosocket.on("connect", function () {
                iosocket.emit('userLogin', { UserName: "123q", UserId: "1" });
                iosocket.on("message", function (msg) {
                    //alert(JSON.stringify(msg));
                    document.getElementById("conent").innerText = JSON.stringify(msg);
                });
            });

        });

    </script>
    <div id="conent"></div>
</body>
</html>
View Code

整个过程主要操作emit事件

完整的测试代码:http://pan.baidu.com/s/1slvstgp 密码:ccie

原文地址:https://www.cnblogs.com/linJie1930906722/p/6391531.html