主线程中未运行websocket-sharp - OnMessage回调

pdkcd3nj  于 2022-11-11  发布在  其他
关注(0)|答案(1)|浏览(269)

我有一个WPF(.NET Framework 4.6)应用程序,它使用websocket-sharp(版本3.0.0)来创建websocket服务器。我有一个WebsocketServer并使用EventHandler将事件传输到MainWindow.xaml.cs,但它不起作用。MainWindow.xaml.cs侦听了RaiseOnScanDevice事件,但未侦听此处调用的任何事件。
我认为这个问题与不同的线程有关。我尝试使用Dispatcher.Invoke,但它仍然不起作用。

System.Windows.Application.Current.Dispatcher.Invoke(new System.Action(() =>
{
    RaiseOnScanDevice(this, new EventArgs());
}));

我发现了一个问题(https://github.com/sta/websocket-sharp/issues/350),但答案不能解决我的问题。
请帮我解决这个问题。
Web套接字服务器. cs文件

public class WebsocketServer : WebSocketBehavior
{
    private static readonly Lazy<WebsocketServer> lazyInstance = new Lazy<WebsocketServer>(() => new WebsocketServer());

    public static WebsocketServer Instance
    {
        get
        {
            return lazyInstance.Value;
        }
    }

    private const string TAG = "WebsocketServer";
    private const string HOST_IP_ADDRESS = "127.0.0.2"; // localhost
    private const int PORT = 38001;

    public WebSocketServer socket;
    private PacketHandler packetHandler = new PacketHandler();

    public event EventHandler<EventArgs> RaiseOnScanDevice = new EventHandler<EventArgs>((a, e) => { });

    public WebsocketServer()
    {
        Initialize();
    }

    public void Initialize()
    {
        socket = new WebSocketServer(IPAddress.Parse(HOST_IP_ADDRESS), PORT);
        socket.AddWebSocketService<WebsocketServer>("/");
        StartServer();
    }

    public void StartServer()
    {
        socket.Start();
    }

    public void StopServer()
    {
        socket.Stop();
    }

    protected override Task OnOpen()
    {
        return base.OnOpen();
    }

    protected override Task OnClose(CloseEventArgs e)
    {
        return base.OnClose(e);
    }

    protected override Task OnError(ErrorEventArgs e)
    {
        return base.OnError(e);
    }

    protected override Task OnMessage(MessageEventArgs e)
    {
        System.IO.StreamReader reader = new System.IO.StreamReader(e.Data);
        string message = reader.ReadToEnd();
        //Converting the event back to 'eventName' and 'JsonPayload'
        PacketModel packet = packetHandler.OpenPacket(message);
        HandleMessageFromClient(packet);
        return base.OnMessage(e);
    }

    private void HandleMessageFromClient(PacketModel packet) {
        var eventName = packet.EventName;
        var data = packet.Data;

        if (eventName == null || eventName.Equals(""))
        {
            return;
        }

        switch (eventName)
        {
            case SocketEvent.Hello:
                Send("OK");
                break;
            case SocketEvent.ScanDevice:
                ScanDevice();
                break;
            default:
                break;
        }
    }

    private void ScanDevice()
    {
        try
        {
            RaiseOnScanDevice(this, new EventArgs());

            // or dispatch to Main Thread
            System.Windows.Application.Current.Dispatcher.Invoke(new System.Action(() =>
            {
                RaiseOnScanDevice(this, new EventArgs());
            }));
        }
        catch (Exception exception)
        {
            Console.WriteLine(exception);
        }
    }
}

主窗口. xaml.cs文件

public partial class MainWindow : Window
{
    public WebsocketServer WebsocketConnection
    {
        get { return WebsocketServer.Instance; }
    }

    public MainWindow()
    {
        InitializeComponent();
        WebsocketConnection.RaiseOnScanDevice += SocketConnection_RaiseOnScanDevice;           
    }

    private void SocketConnection_RaiseOnScanDevice(object sender, EventArgs e)
    {
        Console.WriteLine("SocketConnection_RaiseOnScanDevice");
    }
edqdpe6u

edqdpe6u1#

消息队列是一个好主意,但是你可能需要使用锁来保护对它的访问。最有可能的情况是,这不会是一个问题,但是如果你不这样做,那么你就可能会在WebSocket向队列写入消息时,协程从队列中阅读消息,从而导致错误。例如,你可以这样做:

var queueLock = new object();
var queue = new Queue<MyMessageType>();

// use this to read from the queue
MyMessageType GetNextMessage() 
    {
       lock (queueLock) {
            if (queue.Count > 0) return queue.Dequeue();
            else  return null;
        }
    }

// use this to write to the queue
   void QueueMessage(MyMessageType msg)
    {
        lock(queueLock) {
            queue.Enqueue(msg);
        }
    }

相关问题