使用websocket.sendasock.sendasync()和OnMessage回调函数的WebSocketSha



我正在尝试实现WebSocketSharp库的请求/响应范式,它适用于HTTPCLCLIENT的Request/Response async行为。我正在尝试使用以下代码中给出的异步回调来实现它。我试图使SendAsync方法的OnMessage回调事件等到服务器发送响应。我能够在sendasync方法的范围内获得响应,但是一旦我们摆脱了sendasync范围,就会清除响应的价值。

string clientResponse = null;
            var response = Task.Run(() => objWSClient.SendAsync(stream, Convert.ToInt32(stream.Length), (async (completed) =>
            {
                if (completed)
                {
                    clientResponse = await WSMessageSendSuccess(reqObject, callback);
                    // Websocket response is flushed to the console window, but when it leaves the scope, it doesn't hold the response out of the SendAsync() scope.
                    Console.WriteLine(clientResponse);
                }
                else
                {
                    WSMessageSendFail(reqObject);
                    clientResponse = "Failure to send Message";
                }
            })));

            while (response.Status != TaskStatus.RanToCompletion)
            {
                Task.Delay(10000).Wait();
            }
            response.Wait();
            // As soon as we leave scope of WebSocket.SendAsync() method, it clears the client response variable value.
            // variable name : clientResponse;, it also works same with static property/variable.
            return clientResponse;
static Class WSClient{

        Private Dictionary <string, Func<string, void>> DictWSReqResp = new Dictionary <string, Func<string, void>>();
        Private WebSocket objWSClient;

        public static void init(Iconfiguration config){
            //instantiate objWSClient here, set all handlers, and connect
            objWSClient.OnMessage += new EventHandler<MessageEventArgs>(e_ServerMessageReceived);
        }


        async Task<String> Request(uri, method, payload, headers){
            //it is important that this be an async function and the return be an await, because this way we 
            //guarantee that the taskCS remains in scope of this function. If this were to return the task itself
            //then the tcs will be subject to GC.
            //the three variables below will remain alive while the task is not completed
            TaskCompletionSource<string> taskCS = new TaskCompletionSource<string>();
            string trackid = trackid;
            Action<string> callback;
            //the sendAsync callback should NOT be async
            objWSClient.SendAsync(stream, Convert.ToInt32(stream.Length), new Action<bool>(completed) =>
            {
                if (completed)
                {
                    callback = (payload)=>{ //this will not run unless called by the e_ServerMessageReceived handler
                        taskCS.SetResult(payload);
                        DictWSReqResp.delete(trackid);
                    }
                    DictWSReqResp.Add(trackid, callback);
                }
                else
                {
                    //create well formed errorPayload
                    taskCS.SetException(errorPayload);
                }
            });

            return await taskCS.Task;

        }

        private static void e_ServerMessageReceived(payload){ //server sends {t:1 /*for responses*/, i:<trackid>, p:<response payload>}
            if(t==1)(DictWSReqResp(payload.i))(payload.p);
        }
    }

最新更新