【问题标题】:How to call Server Events (nodejs socket.io) from C# WebSocket4net如何从 C# WebSocket4net 调用服务器事件(nodejs socket.io)
【发布时间】: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

标签: c# websocket socket.io websocket4net


【解决方案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(目标主题),你会发现他们做到了你所说的......
猜你喜欢
  • 2014-06-16
  • 2016-08-20
  • 2019-03-17
  • 1970-01-01
  • 2020-04-09
  • 1970-01-01
  • 1970-01-01
  • 2023-04-08
  • 2019-03-15
相关资源
最近更新 更多