首页 新闻 搜索 专区 学院

WebAPI中使用socket如果在server端回复了再返回值?

0
悬赏园豆:200 [已关闭问题] 关闭于 2015-12-24 20:57
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暴露出来.

数据酷软件的主页 数据酷软件 | 初学一级 | 园豆:130
提问于:2015-12-09 20:47
< >
分享
所有回答(2)
0

你说了半天听不明白你在说什么。不过我从只字片言 结合一下我自己的经验,推论一下,我想你应该表达 的是这个意思:

有个WinFORM 程序,这个WinFORM程序有着对外的WebAPI接口,它对外还有Socket 接口。

别人调用WebAPI接口的时候,你这个WinFORM程序会调用Socket接口,你想要的效果是:这个Socket程序接口返回数据的时候,这个WebAPI接口才会返回数据。

是这个意思么?

田麦成 | 园豆:1988 (小虾三级) | 2015-12-10 09:59

你猜到一半。winform是宿主了webapi,也有socket监听,对内接受客户端端的socket连接,对外暴露api给外界调用。外界调用的时候通过个webapi里面的socket连接这个winform上的socket server。然后socket转发消息给内部的socket客户端过后,需要等处理完才会回复socket server,可是等不到socket server回复webapi就返回值了

支持(0) 反对(0) 数据酷软件 | 园豆:130 (初学一级) | 2015-12-10 20:41

@DataCool:这个模型在我的系统中 也有。

我的处理办法是,请求 WebAPI的时候,设置有超时时间,比如说3秒超时。(如果3秒之内你不给我数据,我就认为没有数据返回)。

在Socket这一端呢,我向Socket发送WebAPI的请求数据。我给WebAPI的请求数据加一个编号,我当然不知道Socket啥时候给我返回数据,所以开了一个异步的线程,只要Socket有返回数据。我就把返回数据存到缓存里(以请求编号为键,缓存数据,这样就可以找到是哪一次请求的数据了,缓存默认30秒过期)。

然后WebAPI请求就在主等待返回数据,肯定不能无限期地等待下去,这里有个请求循环,每个循环 之间延迟100毫秒,最多5次循环。在每次循环中,WebAPI请求都是在缓存中找数据,根据请求编号找对应的返回数据,如果找到请求返回的数据,就直接返回。没找到就循环继续找,直到5次循环结束,还没有找到就认为找不到这条数据。

支持(0) 反对(0) 田麦成 | 园豆:1988 (小虾三级) | 2015-12-11 09:43

@田麦成: 

这个问题一直没解决,现在看你的方法可行。两年前我使用异步委托和信号量这些东西还不熟练。后来把一个API拆分成2个了,一个受理外部请求,回复请求的单号,让2秒后来调另一个接口来查询本次请求的结果。 哈哈哈

支持(0) 反对(0) 数据酷软件 | 园豆:130 (初学一级) | 2017-08-29 16:38
0

在send之后,使用死循环监听数据返回。

幻天芒 | 园豆:36662 (高人七级) | 2015-12-10 09:59
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册