如何处理一些异步TcpClient响应?

时间:2015-08-25 14:06:23

标签: c# web-services asynchronous tcp

萨拉姆。

我在我的项目中使用this class for asynchronous client-server TCP network connection (https://github.com/Phyyl/ObooltNet/blob/master/Source/ObooltNet/NetConnection.cs)

我大部分都连接到“Remote server”并通过TCP连接发送和接收数据(来自另一家公司,我们无法更改除TCP 之外的通信方法)“{{1 }}”。

此“Interface Web Service”句柄“Interface Web Service”请求,创建数据并通过TCP连接传递给“Client Apps”,并传递(响应)解析后的响应“{{1} }“to”Remote server“。

请注意,当前的TCP连接会收到带有 Remote server 事件的“Client Apps”响应。 (此事件很好,我希望将此事件用于后续步骤。)

如何访问和处理这些异步响应并传递“Remote server”请求的完整响应?

总结一下:

  1. OnDataReceivedClient Apps
  2. 发送请求
  3. Client appInterface service
  4. 创建命令
  5. Interface serviceRemote server
  6. 命令的回复
  7. 现在在Remote server,使用 Interface service EVENT处理了回复,我无法从处理Interface service请求的OnDataReceived访问该回复。问题在这里......
  8. 查看此图片以完全了解我的情景:

    Scenario of communications

3 个答案:

答案 0 :(得分:6)

请查看该课程的以下完整(但不是最佳)工作样本。

注意MyHandler.ProcessRequest方法中的while循环。

using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Net.Sockets;
using System.Text;
using System.Web;
using System.Threading.Tasks;

namespace TestApp
{
    class Program
    {

        private static NetConnection fakeServerConnector { get; set; }

        static void Main(string[] args)
        {
            var pageHandler = new MyHandler();
            var tw = Console.Out;
            var builder = new UriBuilder();
            builder.Host = "localhost";
            builder.Port = 80;
            builder.Query = "";

            initFakeServer(8080);

            pageHandler.ProcessRequest(
                new HttpContext(
                    new HttpRequest("index.html", builder.ToString(), ""),
                    new HttpResponse(tw))
                    );

            ConsoleKey key;
            Console.WriteLine(Environment.NewLine + "Press [Enter] or [Esc] to exit!");
            do
            {
                key = Console.ReadKey().Key;
            } while (!(key == ConsoleKey.Enter || key == ConsoleKey.Escape));
        }

        private static void initFakeServer(int Port)
        {
            fakeServerConnector = new NetConnection();
            fakeServerConnector.OnDataReceived += fakeServerConnector_OnDataReceived;
            fakeServerConnector.Start(Port);

        }

        static void fakeServerConnector_OnDataReceived(object sender, NetConnection connection, byte[] e)
        {
            Console.WriteLine(System.Text.UTF8Encoding.UTF8.GetString(e));
            var msg = System.Text.UTF8Encoding.UTF8.GetBytes("Fake Server says: \"Hi\"");
            connection.Send(msg);
        }
    }

    public class MyHandler : IHttpHandler
    {

        public string HostName { get; set; }
        public int Port { get; set; }
        private NetConnection clientConnector { get; set; }
        private bool isReceived;
        private byte[] responsePayload;

        public bool IsReusable
        {
            get { return false; }
        }



        public void ProcessRequest(HttpContext context)
        {            
            HostName = "localhost";
            Port = 8080;

            clientConnector = new NetConnection();
            clientConnector.OnDataReceived += OnDataReceivedHandler;
            clientConnector.Connect(HostName, Port);
            clientConnector.Send(System.Text.UTF8Encoding.UTF8.GetBytes("Client Connector says: \"Hello World\""));
            while (!isReceived)
            {
                // do nothing; wait for isReceived to become true;
            }
            var responsePayloadText = System.Text.ASCIIEncoding.UTF8.GetString(responsePayload, 0, responsePayload.Length);
            context.Response.Write(responsePayloadText + Environment.NewLine);
        }


        public void OnDataReceivedHandler(object sender, NetConnection connection, byte[] data)
        {
            isReceived = true;
            responsePayload = data;
        }
    }    
}

答案 1 :(得分:5)

感谢您阅读并尝试帮助我。

我通过编辑" NetConnection.cs" 类来解决此问题并添加此方法:

public Task<byte[]> SendAndReceiveData(byte[] data, int timeout = 10000)
{
    CheckServerUsedAsClient();
    client.GetStream().Write(data, 0, data.Length);

    Task<byte[]> tskReceive = ReceiveFromAsync(this, timeout, true);
    tskReceive.Wait();

    return tskReceive;
}

并使用此方法从&#34;远程服务器&#34;发送请求和接收数据像这样:

byte[] requestData = createByteArrayCommand();
Task<byte[]> testTask = netConnectionObj.SendAndReceiveData(requestData);
testTask.Wait();

// testTask.Result <= contains server response

答案 2 :(得分:0)

我测试并运行良好的另一种解决方案是 SignalR

使用SignalR hub,我们可以在Client Applications上调用一个类似于Remote server的接收请求的方法,然后创建到Remote server的TCP请求。

收到OnDataReceive(byte[])的响应后(提高 Client Applications ),请在JBAS014777: Services which failed to start: service jboss.persistenceunit."Morfeusflex-ear-1.0.ear/Morfeusflex- ejb-1.0.jar#MorfeusflexPU": org.jboss.msc.service.StartException in service jboss.persistenceunit."Morfeusflex-ear-1.0.ear/Morfeusflex- ejb-1.0.jar#MorfeusflexPU": java.lang.AbstractMethodError 上调用方法并传递回复。