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

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

2、下载SocketIO4Net

SocketIO4Net开源项目结构如下:

进入项目的目录:socketio4net-develop\samples\node.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", "");
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("\r\nConnected event...{0}\r\n", 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}\r\n", 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 = "", 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} \r\n", 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
}
}
} }

修改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\r\n');
debug.config('\tNodejs: %s', process.version);
debug.config('\tsocket.io: v%s', socketio.version);
debug.config('\tListening 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();
});

客户端代码:

<!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>

整个过程主要操作emit事件

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

nodejs即时通讯模块+SocketIO4Net的使用小结的更多相关文章

  1. Nodejs:Node.js模块机制小结

    今天读了<深入浅出Nodejs>的第二章:模块机制.现在做一个简单的小结. 序:模块机制大致从这几个部分来讲:JS模块机制的由来.CommonJS AMD CMD.Node模块机制和包和n ...

  2. nodejs即时聊天

    一直想做一个即时聊天的应用,前几天看到了socket.io,感觉还不错.自己略加改动,感觉挺不错的.官网上给的样例非常easy,以下改进了一点,实现了历史消息的推送. demo地址:chat.code ...

  3. Springboot+Websocket+JWT实现的即时通讯模块

    场景 目前做了一个接口:邀请用户成为某课程的管理员,于是我感觉有能在用户被邀请之后能有个立马通知他本人的机(类似微博.朋友圈被点赞后就有立马能收到通知一样),于是就闲来没事搞了一套. ​ 涉及技术栈 ...

  4. Nodejs + express post get 参数获取小结

    req.params.xxxxx 从path中的变量 req.query.xxxxx 从get中的?xxxx=中 req.body.xxxxx 从post中的变量 Post下别忘了: app.use( ...

  5. 即时搜索(input框)

    做搜索功能的时候,经常遇到输入框检查的需求,最常见的是即时搜索,今天好好小结一下. 即时搜索的方案: (1)change事件    触发事件必须满足两个条件: a)当前对象属性改变,并且是由键盘或鼠标 ...

  6. iOS 即时通讯SDK的集成,快速搭建自己的聊天系统

    现在的外包项目需求变态的各种各样,今天要做社交,明天要加电商,后天又要加直播了,这些系统如果要自己开发,除非大公司技术和人力都够,不然短时间是几乎实现不了的.所以学会灵活利用市面上的各种SDK是灰常重 ...

  7. 即时聊天 / XMPP

    MQTT是第二个即时聊天协议(了解) 5.即时通讯 即时通讯网上有第三方的解决方案,比如环信,融云等.我们是自己搭的xmpp服务器,服务器使用的tigase,之前写过相关的博客,自己去年也做了对应的w ...

  8. input事件在进行模糊搜索时,用到的即时监测input的值变化的方法(即时搜索的input和propertychange方法)

    做搜索功能的时候,经常遇到输入框检查的需求,最常见的是即时搜索,今天好好小结一下. 即时搜索的方案: (1)change事件    触发事件必须满足两个条件: a)当前对象属性改变,并且是由键盘或鼠标 ...

  9. electron + vue 实践项目

    github地址 本地安装环境准备 安装node: * https://nodejs.org/en/download/ 配置webpack: npm install -g webpack(sudo权限 ...

随机推荐

  1. C++构造函数初始化列表与构造函数中的赋值的区别

    C++类中成员变量的初始化有两种方式:构造函数初始化列表和构造函数体内赋值. 一.内部数据类型(char,int……指针等) class Animal { public: Animal(int wei ...

  2. 9、SQL逻辑查询语句执行顺序

    本篇导航: SELECT语句关键字的定义顺序 SELECT语句关键字的执行顺序 准备表和数据 准备SQL逻辑查询测试语句 执行顺序分析 一.SELECT语句关键字的定义顺序 SELECT DISTIN ...

  3. CentOS 7安装Ansible

    在CentOS下安装Ansible非常的简单,但需要注意一下几点: 1.为了简单建议使用yum的epel源安装,毕竟没什么模块需要自己定制的,如果非要指定版本,可以指定不同的版本,下面会讲. 2.母机 ...

  4. 内联汇编中的asm和__asm__

    基本的内联汇编代码: asm格式: asm("assembly code"):   使用替换的关键字: 如果必须的话,可以改变用于标识内联汇编代码段的关键字asm.ANSI C规范 ...

  5. app:processDebugResources

    org.gradle.api.tasks.TaskExecutionException: Execution failed for task ':app:processDebugResources'. ...

  6. Reg 命令修改注册表

    首先要说明:编辑注册表不当可能会严重损坏您的系统.在更改注册表之前,应备份计算机上任何有价值的数据 只有在别无选择的情况下,才直接编辑注册表.注册表编辑器会忽略标准的安全措施,从而使得这些设置会降低性 ...

  7. 【转】CLR和JIT的理解、.NET反汇编学习

    CLR:通用语言运行时(Common Language Runtime)的简称,CLR是.NET框架的核心内容之一,可以把它看为一套标准资源,可以呗任何.NET程序使用.它包括:面向对象的编程模型.安 ...

  8. killall 、kill 、pkill 命令详解 【转】

    之前常用地kill 命令就是 kill -9 XXid;kill -15 XXid;pkill 进程名: 今天发现killall也有适用场景,killall命令对杀死进程组(一个进程中有多线程的情况) ...

  9. Clipboard Action for Mac(智能剪贴板历史管理器)破解版安装

    1.软件简介    Clipboard Action 是 macOS 系统上一款智能剪贴板历史管理器,它允许剪贴板历史中的每一段内容执行操作.使用 AppleScript 或 Automator 工作 ...

  10. 提取aar 包中的jar包,反编译再替换成新的aar

      参考了 http://blog.csdn.net/hekewangzi/article/details/44676797 针对aar包,增加一些说明 aar包本质应该是zip文件.可以用360解压 ...