C# 4.0 Websocketsharp库的请求/响应范例,使用Websocket.SendAsync()和OnMessage回调函数

C# 4.0 Websocketsharp库的请求/响应范例,使用Websocket.SendAsync()和OnMessage回调函数,c#-4.0,.net-core,websocket-sharp,C# 4.0,.net Core,Websocket Sharp,我正在尝试为Websocketsharp库实现请求/响应范例,它与HttpClient的请求/响应异步行为完全相同。我正试图使用下面代码中给出的异步回调来实现它。我试图让SendAsync方法的OnMessage回调事件等待服务器发送响应。我能够在SendAsync方法的作用域内获得响应,但一旦我们离开SendAsync作用域,它就会清除响应的值 string clientResponse = null; var response = Task.Run(() =>

我正在尝试为Websocketsharp库实现请求/响应范例,它与HttpClient的请求/响应异步行为完全相同。我正试图使用下面代码中给出的异步回调来实现它。我试图让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;
静态类WSClient{
私有字典DictWSReqResp=新字典();
私有websocketobjwsclient;
公共静态void init(Iconfiguration配置){
//在此处实例化objWSClient,设置所有处理程序,然后连接
objWSClient.OnMessage+=新事件处理程序(e_ServerMessageReceived);
}
异步任务请求(uri、方法、负载、头){
//重要的是,这是一个异步函数,返回是一个等待,因为这样我们
//保证taskCS仍在此函数范围内。如果要返回任务本身
//然后tcs将接受GC。
//任务未完成时,以下三个变量将保持活动状态
TaskCompletionSource taskCS=new TaskCompletionSource();
字符串trackid=trackid;
动作回调;
//sendAsync回调不应是异步的
objWSClient.sendaync(stream,Convert.ToInt32(stream.Length),新操作(已完成)=>
{
如果(已完成)
{
回调=(有效负载)=>{//除非由e_ServerMessageReceived处理程序调用,否则不会运行此操作
taskCS.SetResult(有效载荷);
DictWSReqResp.delete(trackid);
}
DictWSReqResp.Add(trackid,回调);
}
其他的
{
//创建格式良好的错误负载
taskCS.SetException(errorPayload);
}
});
返回等待任务cs.Task;
}
私有静态void e_ServerMessageReceived(有效负载){//服务器发送{t:1/*用于响应*/,i:,p:}
如果(t==1)(DictWSReqResp(payload.i))(payload.p);
}
}

您可以按照Microsoft的文章来封装API,很抱歉这篇文章太难看了。这是我解决与你的问题大致相同的问题的方法。服务器响应是一个带有负载的JSON对象。剩下的是不言自明的,还有一点逻辑缺失。我的类将REST消息转换为WS-payload。
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);

        }

    }