public ApiActionResult BufferBox_API_Request(string StationNo, string CellNo, string Action) { var result = new ApiActionResult() { Success = false, Result = null, Message = "操作失败。" }; byte[] results = new byte[1024]; try { if (!clientSocket.Connected) { clientSocket.Connect(new IPEndPoint(IPAddress.Parse(conf.AppSettings.Settings["Middleware_IP"].Value), Convert.ToInt32(conf.AppSettings.Settings["Middleware_PORT"].Value))); } using (var db = new BufferBoxDBEntities()) { var stationEntity = db.station_signin_session.Where(st => st.SessionDict == StationNo).FirstOrDefault(); if (stationEntity == null) { result.Message = "设备不存在或者设备编号有误!"; result.Result = ""; return result; } var requestEntity = new API_Request_session { API_Request_IP = Request.GetClientIpAddress(), RequestID = Guid.NewGuid(), RequestData = CellNo + "|" + Action, RequestDataTime = DateTime.Now, ResultData = "", ExecuteFlag = false, StationNo = StationNo }; db.API_Request_session.AddObject(requestEntity); db.SaveChanges(); clientSocket.Send(Encoding.UTF8.GetBytes("api_request:" + JsonConvert.SerializeObject(requestEntity))); result.Success = true; result.Message = "设备已经受理请求。"; result.Result = requestEntity.RequestID.ToString(); } } catch (Exception ex) { result.Message = "中间件发生异常:" + ex.Message; } return result;
详细场景见上面的代码,不等clientSocket.Receive()就马上返回了,如何使用同步的方法等到server回复才能返回。现在是采取先存数据库一次外部的请求产生一个请求序号,外部需要带上这个序号调另一个api查询上次请求的结果。
sync await 是否能解决问题呢。没有这样编码的经验,求高手指点。webapi使用winform宿主,owin.net winform运行着一个socket server.远端的工控设备作为socket client接受外部请求,不考虑直接把远端的工控设备作为socket client暴露出来.
你说了半天听不明白你在说什么。不过我从只字片言 结合一下我自己的经验,推论一下,我想你应该表达 的是这个意思:
有个WinFORM 程序,这个WinFORM程序有着对外的WebAPI接口,它对外还有Socket 接口。
别人调用WebAPI接口的时候,你这个WinFORM程序会调用Socket接口,你想要的效果是:这个Socket程序接口返回数据的时候,这个WebAPI接口才会返回数据。
是这个意思么?
你猜到一半。winform是宿主了webapi,也有socket监听,对内接受客户端端的socket连接,对外暴露api给外界调用。外界调用的时候通过个webapi里面的socket连接这个winform上的socket server。然后socket转发消息给内部的socket客户端过后,需要等处理完才会回复socket server,可是等不到socket server回复webapi就返回值了
@DataCool:这个模型在我的系统中 也有。
我的处理办法是,请求 WebAPI的时候,设置有超时时间,比如说3秒超时。(如果3秒之内你不给我数据,我就认为没有数据返回)。
在Socket这一端呢,我向Socket发送WebAPI的请求数据。我给WebAPI的请求数据加一个编号,我当然不知道Socket啥时候给我返回数据,所以开了一个异步的线程,只要Socket有返回数据。我就把返回数据存到缓存里(以请求编号为键,缓存数据,这样就可以找到是哪一次请求的数据了,缓存默认30秒过期)。
然后WebAPI请求就在主等待返回数据,肯定不能无限期地等待下去,这里有个请求循环,每个循环 之间延迟100毫秒,最多5次循环。在每次循环中,WebAPI请求都是在缓存中找数据,根据请求编号找对应的返回数据,如果找到请求返回的数据,就直接返回。没找到就循环继续找,直到5次循环结束,还没有找到就认为找不到这条数据。
@田麦成:
这个问题一直没解决,现在看你的方法可行。两年前我使用异步委托和信号量这些东西还不熟练。后来把一个API拆分成2个了,一个受理外部请求,回复请求的单号,让2秒后来调另一个接口来查询本次请求的结果。 哈哈哈
在send之后,使用死循环监听数据返回。