.NET 基于Socket中转WebSocket

这篇具有很好参考价值的文章主要介绍了.NET 基于Socket中转WebSocket。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

前言

针对IOS App Proxy Server无法直连WebSocket,建立 Socket中转端。

.NET 基于Socket中转WebSocket,.NET,.net

WebSocket

WebSocket 端用于实现实时通信功能。

WebSocket 端通过 WebSocket 协议与中转端通信,中转端可以通过 WebSocket 或其他传输协议与 WebSocket 端建立连接,收发消息。

定义 SendMessageToChatRoomIP 和 JoinChatRoom,用于处理来自客户端的消息和连接事件。

中转端 C1 (Socket Server)

中转端 C1 是一个独立的应用程序,用于连接WebSocket端,建立Socket服务。

中转端 C1 的主要功能是接收来自客户端 C2 的消息,并将其转发给 WebSocket 端,或者接收来自 WebSocket 端的消息,并转发给客户端 C2。

客户端 C2 x  N

客户端 C2 ,主要与中转端连接 发送数据,接收数据。

在客户端 C2 中,连接到中转端 C1、发送消息给中转端 C1、接收来自中转端 C1 的消息。

调用关系为:

客户端 C2 通过与中转端 C1 的通信,向 WebSocket 端发送消息或接收来自 WebSocket 端的消息。

中转端 C1 接收来自客户端 C2 的消息,并将其转发给 WebSocket 端,或者接收来自 WebSocket 端的消息,并转发给客户端 C2。

.NET 基于Socket中转WebSocket,.NET,.net

中转端实现

1.连接WebSocket

      public async Task ConnectToServer()
      {
          try
          {
              connection = new HubConnectionBuilder()
                  .WithUrl("xxx/chathub")//
                  .Build();

              connection.On<string, string, string, string>("ReceiveMessage", async (user, message, clientIP, chatRoomId) =>
              {
                  Console.WriteLine($"Received message from wsserver_sr : {user}: {message} |socketserver {clientIP}|{chatRoomId}");

                  // 收到来自服务器的消息时,向客户端 C2 发送消息
                  await SendMessageToClientC2(user, message, clientIP, chatRoomId);
              });

              await connection.StartAsync();
          }
          catch (Exception ex)
          {
              Console.WriteLine($"Error connecting to SignalR server: {ex.Message}" + Environment.NewLine);
          }
      }

 收到消息时发送给对应客户端

       public async Task SendMessageToClientC2(string user, string message, string clientIP, string chatRoomId)
       {
           // 根据 chatRoomId 找到对应的客户端 C2,并发送消息
           if (chatRooms.ContainsKey(chatRoomId))
           {
               byte[] data = Encoding.ASCII.GetBytes($"{user}  {message}  |{clientIP}|{chatRoomId} ");
               foreach (var client in chatRooms[chatRoomId])
               {
                   await client.GetStream().WriteAsync(data, 0, data.Length);
               }
           }
           else
           {
               Console.WriteLine($"Chat room {chatRoomId} does not exist" + Environment.NewLine);
           }
       }

2.建立中转端Socket端口

   public void StartListening()
   {
       if (!listening)
       {
           try
           {
               int port = 10086; // 监听端口
               server = new TcpListener(IPAddress.Any, port);
               server.Start();
               listening = true;
               Console.WriteLine($"Server listening on port {port}" + Environment.NewLine);

               Task.Run(() => AcceptClients());
           }
           catch (Exception ex)
           {
               Console.WriteLine($"Error starting server: {ex.Message}" + Environment.NewLine);
           }
       }
   }

3.向客户端发消息


        public async Task AcceptClients()
        {
            while (listening)
            {
                try
                {
                    TcpClient client = await server.AcceptTcpClientAsync();
                    Task.Run(() => HandleClient(client));
                }
                catch (Exception ex)
                {
                    Console.WriteLine($"Error accepting client: {ex.Message}" + Environment.NewLine);
                }
            }
        }

4.监听客户端连接

   public async Task AcceptClients()
   {
       while (listening)
       {
           try
           {
               TcpClient client = await server.AcceptTcpClientAsync();
               Task.Run(() => HandleClient(client));
           }
           catch (Exception ex)
           {
               Console.WriteLine($"Error accepting client: {ex.Message}" + Environment.NewLine);
           }
       }
   }

5.处理客户端连接

    public async Task HandleClient(TcpClient client)
    {
        NetworkStream stream = client.GetStream();
        byte[] buffer = new byte[1024];
        int bytesRead;

        while (client.Connected)
        {
            try
            {
                bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length);
                string message = Encoding.ASCII.GetString(buffer, 0, bytesRead);
                ProcessMessage(message, client);
            }
            catch (Exception ex)
            {
                Console.WriteLine($"Error receiving message: {ex.Message}" + Environment.NewLine);
                break;
            }
        }

        // 客户端断开连接时,从聊天室中移除
        foreach (var chatRoomId in chatRooms.Keys)
        {
            if (chatRooms[chatRoomId].Contains(client))
            {
                chatRooms[chatRoomId].Remove(client);
                Console.WriteLine($"Client disconnected from chat room {chatRoomId}" + Environment.NewLine);
                break;
            }
        }
    }

6.处理连接

        public async void ProcessMessage(string message, TcpClient client)
        {
            string[] parts = message.Split('|');
            if (parts.Length >= 2)
            {
                string command = parts[0];
                string chatRoomId = parts[1];

                switch (command)
                {
                    case "JoinChatRoom":
                        await JoinChatRoom(chatRoomId, client);
                        break;
                    case "SendMessageToChatRoomIP2":
                        if (parts.Length >= 4)
                        {
                            string user = parts[2];
                            string msg = parts[3];
                            //  await SendMessageToChatRoom(chatRoomId, user, msg);
                            await SendMessageToChatRoomAddress(chatRoomId, user, msg, client);
                        }
                        break;
                    default:
                        Console.WriteLine($"Invalid command: {command}" + Environment.NewLine);
                        break;
                }
            }
        }

JoinChatRoom 异步调用服务端的JoinChatRoom 

SendMessageToChatRoomIP2 异步调用SendMessage  

7.运行

本地运行

.NET 基于Socket中转WebSocket,.NET,.net

发布到linux

.NET 基于Socket中转WebSocket,.NET,.net

run  Server listening on port 10860

netstat -tln查看端口 (tuln) 

也可以优化封装成WinForm程序,收发消息可视化。

点击启动socket端口调用 1.连接websocket 2.监听socket   

.NET 基于Socket中转WebSocket,.NET,.net

也可以封装成系统服务,与进程一样藏在后台运行。

客户端实现

1.连接Socket端

   private async void MainForm_Load(object sender, EventArgs e)
   {
       try
       {
           client = new TcpClient();
           await client.ConnectAsync("192.168.80.123", 10086); 
           stream = client.GetStream();
           connected = true;

           // 连接成功后,调用 JoinChatRoom 方法加入聊天室
           await JoinChatRoom("room001");

           Task.Run(ReceiveMessages);
       }
       catch (Exception ex)
       {
           textBoxReceivedMessages.AppendText($"Error connecting to server: {ex.Message}" + Environment.NewLine);
       }
   }

 2.加入ChatRoom

JoinChatRoom中转到Server端再加入聊天室

   private async Task JoinChatRoom(string chatRoomId)
        {
            // 发送消息给中转端 C1,请求加入聊天室
            byte[] data = Encoding.ASCII.GetBytes($"JoinChatRoom|{chatRoomId}|J");
            await stream.WriteAsync(data, 0, data.Length);
        }

3.发送消息

发送到Socket中转端

     
        private async Task SendMessageToChatRoom(string chatRoomId, string message)
        {
            // 发送消息给中转端 C1,请求向指定聊天室发送消息
            byte[] data = Encoding.ASCII.GetBytes($"SendMessageToChatRoomIP2|{chatRoomId}|client2m|{message}");
            await stream.WriteAsync(data, 0, data.Length);
        }

        

4.接收消息

private async Task ReceiveMessages()
        {
            byte[] buffer = new byte[1024];
            int bytesRead;

            while (connected)
            {
                try
                {
                    bytesRead = await stream.ReadAsync(buffer, 0, buffer.Length);
                    string message = Encoding.ASCII.GetString(buffer, 0, bytesRead);
                    DisplayMessage(message);
                }
                catch (Exception ex)
                {
                    textBoxReceivedMessages.AppendText($"Error receiving message: {ex.Message}" + Environment.NewLine);
                }
            }
        }

        private void DisplayMessage(string message)
        {
            if (InvokeRequired)
            {
                Invoke(new Action<string>(DisplayMessage), message);
                return;
            }

            textBoxReceivedMessages.AppendText(message + Environment.NewLine);
        }

     

5.点击事件

Send

   private async void buttonSend_Click(object sender, EventArgs e)
        {
            if (!connected)
            {
                textBoxReceivedMessages.AppendText("Not connected to server." + Environment.NewLine);
                return;
            }

            string message = textBoxSendMessage.Text;

            if (!string.IsNullOrEmpty(message))
            {
                // 发送消息给中转端 C1,请求向聊天室发送消息
                await SendMessageToChatRoom("room001", message);
                textBoxSendMessage.Clear();
                textBoxReceivedMessages.AppendText("Sent message to chat room: room001"  + Environment.NewLine);
            }
            else
            {
                textBoxReceivedMessages.AppendText("Please enter a message." + Environment.NewLine);
            }
        }

6.运行

.NET 基于Socket中转WebSocket,.NET,.net

服务端启动

Server listening on port 10086

服务端发收发消息到中转端

Sent message to chat room: room001
client2m  hihihi|socketclient 192.168.80.123  |::ffff:183.7.113.105|room001 
 

中转端拿到客户端信息->WebSocket端->中转端接收->客户端接收

Client joined chat room room001
Received message from WSSserver_sr : client2m: hihihi|socketclient 192.168.80.123 |socketserver:::ffff:183.7.113.105|room001

客户端也可以用IOS SOCKET5发送消息

//...         
 dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                    NSData * sendData = [@"JoinChatRoom|room001" dataUsingEncoding:NSUTF8StringEncoding];
                    [self.socket writeData:sendData withTimeout:-1 tag:1];
                    
                    dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(1 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
                        NSData * sendData = [@"SendMessageToChatRoomIP2|room001|userid001|hello" dataUsingEncoding:NSUTF8StringEncoding];
                        [self.socket writeData:sendData withTimeout:-1 tag:2];
                        [self.socket readDataWithTimeout:-1 tag:1];
                    });
                });

//...

Run

.NET 基于Socket中转WebSocket,.NET,.net文章来源地址https://www.toymoban.com/news/detail-860276.html

到了这里,关于.NET 基于Socket中转WebSocket的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • rabbitmq模块启动报java.net.SocketException: socket closed的解决方法

    问题 最近在接手一个项目时,使用的是spring-cloud微服务构架,mq消息消费模块是单独一个模块,但启动这个模块一直报如下错误: 这个错误是这个模块注册不到nacos报的错,刚开始就是检查模块的nacos配置和rabbitmq的配置,都没发现问题!后面详情看错误时发现还有这么一个警

    2024年02月16日
    浏览(49)
  • 关于ASP.NET Core WebSocket实现集群的思考

    前言     提到 WebSocket 相信大家都听说过,它的初衷是为了解决客户端浏览器与服务端进行双向通信,是在单个 TCP 连接上进行全双工通讯的协议。在没有WebSocket之前只能通过浏览器到服务端的请求应答模式比如轮询,来实现服务端的变更响应到客户端,现在服务端也可以主

    2024年04月14日
    浏览(47)
  • ASP.NET Core 中使用 WebSocket 协议进行实时通信

    介绍 在 ASP.NET Core 中使用 WebSocket 协议创建实时通信的完整示例涉及几个步骤。在此示例中,我们将创建一个简单的聊天应用程序,用户可以在其中实时发送和接收消息。此示例假设您对 ASP.NET Core 和 C# 有基本了解。 步骤1.创建一个新的ASP.NET Core项目 首先,使用 Visual Studio 或

    2024年01月25日
    浏览(51)
  • Linux 下 Java Socket 编程报 java.net.Exception:Permission denied (权限不足)

    本人用Linux部署springboot项目时遇见这个错误,原因很简单,就是端口号没有选对。 在linux系统中,端口号再1024以下的需要root权限,只要把端口改成大于1024的就可以了,但避开一些软件的默认端口,如Tomcat的8080端口,mysql的3306端口。 解决方法: 设置临时属性重新启动即可。

    2024年02月11日
    浏览(41)
  • Unity3D 网络游戏框架(二、同步Socket) 参考连接:Socket 类 (System.Net.Sockets) | Microsoft Learn

    1、Socket.Connect() 2、Socket.Send() 3、Socket.Receive() 在了解完Socket通讯流程图和相关API之后我们来开发客户端代码:  在Unity中添加 两个Button、一个InputField和有Text ,Connect 方法 绑定连接的按钮, Send 方法绑定发送按钮。 Connect :客户端点击连接后会和服务端进行连接,这里面127

    2024年02月16日
    浏览(49)
  • 推荐一个.Net Core开发的Websocket群聊、私聊的开源项目

    今天给大家推荐一个使用Websocket协议实现的、高性能即时聊天组件,可用于群聊、好友聊天、游戏直播等场景。 这是一个基于.Net Core开发的、简单、高性能的通讯组件,支持点对点发送、群聊、在线状态的订阅。 该项目还包含群聊例子,可以用于学习。 1、跨平台:基于.N

    2024年02月03日
    浏览(58)
  • 在使用socket进行通信连接时出现java.net.SocketException: Connection reset的解决方案

    在创建客户端和服务端后,出现java.net.SocketException: Connection reset的错误。 导致的原因 客户端或者服务端其中一端还在传输数据的途中,另外一端的socket被关闭(或者主动0关闭,或者运行异常退出导致的关闭),这时,客户端的第一个数据包传输过来后就会引发该异常。 一端

    2024年02月09日
    浏览(50)
  • 微信小程序如何使用原生Websocket与Asp.Net Core SignalR 通信

    如题,这可能算是.net 做小程序的服务端时,绕不开的一个问题,老生常谈了。同样的问题,我记得我2018/19年的一个项目的解决方案是: 修改官方的SignalR.js的客户端 :把里面用到浏览器的Websocket改成微信小程序的官方api的。目前网上也有不少这样的方案,已经改好开源了;

    2024年02月08日
    浏览(62)
  • websocket报org.apache.tomcat.util.net.NioEndpoint$NioSocketWrapper.fillReadBuffer错误

    当前项目中需要对websocket长时间的推送数据,但是在谷歌浏览器中就链接相对稳定,在安卓发布屏中会存在15min-60min或者更长时间的断开,报错信息如下: 修改反向代理,这种方式无法无限延长连接时常,组里尝试使用反向代理之后的链接直连,如果网络不通的话,此方式失

    2024年02月13日
    浏览(39)
  • Winform中使用Websocket4Net实现Websocket客户端并定时存储接收数据到SQLite中

    SpringBoot+Vue整合WebSocket实现前后端消息推送: SpringBoot+Vue整合WebSocket实现前后端消息推送_websocket vue3.0 springboot 往客户端推送-CSDN博客 上面实现ws推送数据流程后,需要在windows上使用ws客户端定时记录收到的数据到文件中,这里 文件使用SQLite数据库进行存储。 Winform中操作Sql

    2024年02月22日
    浏览(49)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包