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