如何从 C# WebSocket4net 调用服务器事件(nodejs socket.io)

Posted

技术标签:

【中文标题】如何从 C# WebSocket4net 调用服务器事件(nodejs socket.io)【英文标题】:How to call Server Events (nodejs socket.io) from C# WebSocket4net 【发布时间】:2019-04-18 08:37:44 【问题描述】:

我正在为 nodejs 中实现的服务器设置 C# websocket 客户端(使用 socket.io)。使用 [Websocket4net]:https://github.com/kerryjiang/WebSocket4Net。 我的代码能够与套接字服务器连接,但 WebClient.Send("message") 不会调用服务器事件。 我被困在使用 websocket4net lib 从服务器发送消息或调用事件。我选择这个库是因为我的实现是在框架 2.0 或更低版本中。

我尝试使用 websocket.send("message") 在连接后调用消息事件,但在服务器上无法识别。在服务器调用函数失败。还研究了执行命令,但无法在我的课堂上实现这一点。

public class JniorWebSocket : IDisposable

    //public delegate void LogEventHandler(object sender, LogEventArgs args);
    //public event LogEventHandler Log;
    public event EventHandler Connected;
    public event EventHandler Disconnected;

    private WebSocket _websocket;
    private string _uri;
    private string sid;

    public JniorWebSocket(string host) : this(host, 0)  

    public JniorWebSocket(string host, int port)
    
        _uri = "ws://" + host;
        if (0 != port) _uri += ":" + port + "/join/?EIO=3&transport=websocket";

        _websocket = new WebSocket(_uri);
        _websocket.Opened += new EventHandler(websocket_Opened);
        _websocket.Error += Websocket_Error;
        _websocket.Closed += websocket_Closed;
        _websocket.MessageReceived += Websocket_MessageReceived;

        _websocket.Open();
    

    public void Dispose()
    
        _websocket.Dispose();
        GC.SuppressFinalize(this);
    
    public bool AllowUnstrustedCertificate
    
        get
        
            return _websocket.AllowUnstrustedCertificate;
        
        set
        
            _websocket.AllowUnstrustedCertificate = value;
        
    

    public void Connect()
    
        _websocket.Open();
        while (_websocket.State == WebSocketState.Connecting)  ;
        if (_websocket.State != WebSocketState.Open)
        
            throw new Exception("Connection is not opened.");
        
    

    public void Close()
    
        _websocket.Close();
    

    public void Send(string message)
    
        try
        
            _websocket.Send(message);
        
        catch (Exception ex)
        
        
    
    private void Websocket_Error(object sender, ErrorEventArgs e)
    
    

    private void Websocket_MessageReceived(object sender, MessageReceivedEventArgs e)
    
        if (e.Message.IndexOf("") != -1)
        
            var json = JObject.Parse(e.Message.Substring(e.Message.IndexOf("")));

            sid = json["sid"].ToString();

            Console.WriteLine(sid);
            if ("Error".Equals(sid)) HandleErrorMessage(json);
        
    
    private void HandleErrorMessage(JObject json)
    
    
    private void websocket_Opened(object sender, EventArgs e)
    
        Connected?.Invoke(this, EventArgs.Empty);
        Send(string.Empty);
    

    private void websocket_Closed(object sender, EventArgs e)
    
        Disconnected?.Invoke(this, EventArgs.Empty);
    

从我的 main 调用这个类

JniorWebSocket jniorWebSocket = new JniorWebSocket(uri, port);
jniorWebSocket.AllowUnstrustedCertificate = true;
jniorWebSocket.Connect();
jniorWebSocket.Send("message");

nodejs 端的socket.io

const server = require('http').Server(app);
global.socketIO = SocketIO(server,  path: '/join' );
global.socketIO.on('connection', (socket) => 

    socket.on('message',async (data) => 
        console.info(data);
    );
    socket.on('authenticate', async (data) => 
        try 
             
         catch(error) 
            console.warn('Error while authenticating socket', error);
        
    );
);

我是这个 websocket C# 实现的新手,不知道如何调用服务器事件,之后我也会在客户端编写一些事件。 期望从客户端调用所有服务器事件。

【问题讨论】:

我也有同样的问题..你的问题解决了吗?谢谢 @ertan2002 不幸的是没有...... .net 端没有可用于套接字的实现。或者一半可用我可以说。我将创建 github repo 并实现它。 我已经通过使用 SocketIoClientDotNet 解决了这个问题。请注意,您应该提供不带任何扩展名(例如 EIO 或传输等)的直接 url,例如:localhost:1453,它适用于桌面和 xamarin.mobile,我的框架是 4.5 【参考方案1】:

它适用于桌面应用和 xamarin.android 应用

我已经使用过这个库,即使它已被弃用 https://github.com/Quobject/SocketIoClientDotNet

你可以直接从nugetInstall-Package SocketIoClientDotNet安装

using Quobject.EngineIoClientDotNet.Client.Transports;
using Quobject.SocketIoClientDotNet.Client;



     var option = new IO.Options()
                
                  QueryString = "Type=Desktop",
                  Timeout = 5000,
                  ReconnectionDelay = 5000,
                  Reconnection = false,                   
                  ransports = Quobject.Collections.Immutable.ImmutableList.Create<string>(PollingXHR.NAME)
                ;

                socket = IO.Socket("http://localhost:1453",option);
                socket.On(Socket.EVENT_CONNECT, () =>
                
                    socket.Emit("iAmOnline", "1234");

                );
                socket.On("youAreOnline", () =>
                
                    Console.WriteLine("I am Online");
                );

                socket.On("hi", (data) =>
                
                    Console.WriteLine(data);
                    socket.Disconnect();
                );

您可以根据需要添加任何传输。由于防火墙,我添加了 xhr-polling。您可以使用 WebSocket.NAME 和/或 Polling.NAME

【讨论】:

.Net 4.5 版我也可以这样做 我需要与 .net 2.0 兼容并使用 webhttprequest 的 backword?您是否也遵循 socket.io 协议,例如首先使用 http 然后使用 websocket 进行长轮询,然后创建房间并进行通信? @BhushanGholave 我也想拥有 .net 标准(不确定您是在谈论 .net 2.0 框架还是标准),但不支持 .net 标准.. 为什么你会使用 webhttprequest?阅读engine.io(目标主题),你会发现他们做到了你所说的......

以上是关于如何从 C# WebSocket4net 调用服务器事件(nodejs socket.io)的主要内容,如果未能解决你的问题,请参考以下文章

如何从 C# 代码调用 Google 地理编码服务

Websocket客户端断开websocket4net

SuperWebSocket实现服务端和WebSocket4Net实现客户端

如何从 c# web 服务调用 c++ Opencv 项目?

如何从网页Javascript调用C#方法? [关闭]

如何通过 JavaScript 从服务器端的网页调用客户端 C# 程序函数?