基于webapi的websocket聊天室(番外一)

上一篇我已经实现了聊天室,并且在协议中实现了4种类型的消息传输。其实还可以添加videoaudiolive 等等类型。

不过假如把目前的协议看作RCP1.0版的话,这个版本就只支持有限的4种消息。精力有限啊。也许RCP2.0就可以把videoaudio 类型加进去?

这不是这篇番外考虑的。而是我在定义和实现协议的过程中注意到了一些问题。

系统的网络缓冲区是怎么回事?

因为我自己定义了一个400字节的buffer用来接收消息。如果接收到的消息超出了400字节,WebSocket会给出提示,将EndOfMessage字段设置为false。

这到底是

  • 客户端暂停了本次发送,等到服务器再一次执行ReceiveAsync方法时才继续发送?
  • 还是WebSocket对象本身内置了缓冲区?消息全部都暂存在缓冲区?

我使用浏览器开发者工具监视了ws消息发送过程,结合后台断点调试,发现WebSocket采用了第二种方案。把消息全部存在缓冲区,我用buffer读一次,就取出来一点。

既然是缓冲区,那么一个WebSocket对象的内置缓冲区有多大?客户端发送的文件长度超过了WebSocket对象的内置缓冲区的大小时怎么办?

看看websocket协议怎么说

看起来websocket 协议中数据长度上限为 2^127,可以认为没有限制。因而在实际使用中 websocket 消息长度限制只取决于服务器实现。

System.Net.WebSockets.WebSocket对象内部一定使用了一个MemoryStream之类的东西来暂存数据。

问题是那为什么他不直接把那个缓冲区给我?我还要自己再去创建一个缓冲区,从他的缓冲区读数据?我不太清楚。

多个WebSocket与http服务器怎么共用一个端口?

典型的socket监听{IP:Port}

但是我在websocket中没有看到这些信息。

如果你的 Web API 服务器在端口 80 上运行,那么 WebSocket 连接也会使用端口 80 来传输数据

比较疑惑的是,操作系统接收到一个TCP数据包,怎么知道交给http服务器,还是哪个websocket连接?

原来一个TCP端口可以建立多个TCP连接,只要**(服务器IP:服务器Port:客户端IP:客户端Port)** 唯一就行。

看看调试

TCP连接 服务器IP 服务器Port 客户端IP 客户端Port 连接Id
游客_1 ::1 5234 ::1 54008 0HN3PID8UHKHN
游客_2 ::1 5234 ::1 54481 0HN3PID8UHKHO
游客_3 ::1 5234 ::1 54556 0HN3PID8UHKHP

操作系统就是根据这个表决定把从端口接收的数据发往哪个游客线程。

看看实际连接是怎么样的?

手动管理连接看看?

由于websockt我们看不到客户端发起连接,服务端接收连接的过程,我自己用socket测试一下。

代码非常简单

  • 服务器监听端口
  • 等待客户端连接,然后维护到一个集合中
  • 每接到连接,就开启一个聊天线程
csharp 复制代码
    static void Main(string[] args)
    {
        //服务器
        if (args.Length == 1) { 
            int serverPort = Convert.ToInt32(args[0]);
            var server = new TcpListener(IPAddress.Parse("127.0.0.1"),serverPort);
            Console.WriteLine($"TCP服务器  127.0.0.1:{serverPort}");
            server.Start();
            int cnt = 0;
            Task.Run(async() =>
            {
                List<TcpClient> clients= new List<TcpClient>();
                while (true)
                {
                    TcpClient client = await server.AcceptTcpClientAsync();
                    clients.Add(client);
                    cnt++;
                    var ep = client.Client.RemoteEndPoint as IPEndPoint;
                    Console.WriteLine($"TCP客户端_{cnt}  {ep.Address}:{ep.Port}");
                    //给这个客户端开一个聊天线程
                    //操作系统将会根据游客端口对应表将控制权交给对应游客线程
                    StartChat(client);
                }
            }).Wait();
        }
        //客户端
        else if (args.Length == 3)
        {
            int clientPort = Convert.ToInt32(args[0]);
            int serverPort = Convert.ToInt32(args[1]);
            string msg = args[2];
            var client=new TcpClient(new IPEndPoint(IPAddress.Parse("127.0.0.1"), clientPort));
            Console.WriteLine($"TCP客户端  127.0.0.1:{clientPort}");
            Task.Run(async () =>
            {
                await client.ConnectAsync(new IPEndPoint(IPAddress.Parse("127.0.0.1"), serverPort));
                Console.WriteLine($"连接到 127.0.0.1:{serverPort}");
                //打招呼
                var msgBytes=UTF8Encoding.UTF8.GetBytes(msg);
                await client.Client.SendAsync(msgBytes);
                //等待数据,阻塞在这里,保持连接
                await client.Client.ReceiveAsync(new ArraySegment<byte>(new byte[100]));
            }).Wait();
        }
    }

    public static async Task StartChat(TcpClient client)
    {
        var buffer = new byte[100];
        while (true)
        {
            //阻塞接收消息
            int msgLength = await client.Client.ReceiveAsync(new ArraySegment<byte>(buffer));
            string str=UTF8Encoding.UTF8.GetString(buffer,0,msgLength);
            Console.WriteLine(str);
        }
    }
}

我们测试建立一个服务端,和三个连接到这个服务端的客户端

虽然三个游客都向一个服务器端口5234发送消息,但操作系统根据端口连接对应表知道将消息发送给哪个线程。就好像在一个端口划分出来了3个信道。

  • 每个信道可以使用具体的http协议或我们写的RCP协议来序列化和反序列化
  • 要注意的是,这些不同的连接(TcpClient)是同一个TCPLisener对象到的。这就是在一个程序中使用多种通信协议。
相关推荐
蟾宫曲1 天前
网络编程 03:端口的定义、分类,端口映射,通过 Java 实现了 IP 和端口的信息获取
java·网络·网络编程·ip·端口
龙少95432 天前
【Http,Netty,Socket,WebSocket的应用场景和区别】
java·后端·websocket·网络协议·http
m0_748232922 天前
前端在WebSocket中加入Token
前端·websocket·网络协议
等一场春雨2 天前
react websocket 全局访问和响应
前端·websocket·react.js
流穿2 天前
WebSocket vs SSE:实时通信技术的对比与选择
网络·websocket·网络协议·大语言模型·sse
_.Switch2 天前
FastAPI 的进阶应用与扩展技术:异步编程与协程、websocket、celery
网络·数据库·python·websocket·网络协议·性能优化·fastapi
Onlooker1292 天前
实现 WebSocket 接入文心一言
网络·websocket·网络协议
kikyo哎哟喂2 天前
计算机网络基础--WebSocket
websocket·网络协议·计算机网络
G丶AEOM2 天前
WebSocket了解
网络·websocket·网络协议
m0_748230943 天前
websocket 局域网 webrtc 一对一 多对多 视频通话 的示例
websocket·音视频·webrtc