Kotlin的WebSocketSession在C#中的等效对象及实现验证
问题分析与解答
你当前的C# initSession方法仅完成了WebSocket对象的实例化,和Kotlin中initSession的功能并不完全等效——Kotlin的client.webSocketSession是挂起函数,会主动发起WebSocket连接并等待连接建立完成后才返回,而你的代码只是创建了对象,没有触发实际的连接动作。
关键差异与修正方向
- 连接建立:需要在实例化WebSocket后,主动调用连接方法(对应Kotlin中
webSocketSession的连接逻辑)。 - 异步处理:C#的WebSocket操作都是异步的,建议用
async/await模式,和Kotlin的挂起函数行为对齐。 - 完整功能对应:需要补充
send、消息监听、closeSession的实现,才能和你Kotlin中的WebSocketServiceImpl功能完全匹配。
等效的C#实现示例
假设使用.NET标准库中的ClientWebSocket(C#官方推荐的WebSocket客户端实现),完整实现如下:
using System.Net.WebSockets; using System.Text; using System.Text.Json; public class WebSocketServiceImpl { private ClientWebSocket? _socket; // 对应Kotlin的initSession,异步发起连接 public async Task InitSession(string username) { _socket = new ClientWebSocket(); // 连接到指定WebSocket地址,带username参数 var uri = new Uri($"ws://xxx.xxx.xxx.xxx:xxxx/myRoute?username={username}"); await _socket.ConnectAsync(uri, CancellationToken.None); // 连接成功后启动消息监听任务 _ = ListenForMessages(); } // 对应Kotlin的send方法,序列化对象并发送文本帧 public async Task Send(MyObj myObj) { if (_socket?.State != WebSocketState.Open) return; try { var json = JsonSerializer.Serialize(myObj); var buffer = Encoding.UTF8.GetBytes(json); await _socket.SendAsync( new ArraySegment<byte>(buffer), WebSocketMessageType.Text, endOfMessage: true, CancellationToken.None); } catch (Exception ex) { Console.WriteLine(ex.ToString()); } } // 对应Kotlin的observePrintableMessages,监听并解析消息 private async Task ListenForMessages() { if (_socket == null) return; var buffer = new byte[1024 * 4]; try { while (_socket.State == WebSocketState.Open) { var result = await _socket.ReceiveAsync( new ArraySegment<byte>(buffer), CancellationToken.None); if (result.MessageType == WebSocketMessageType.Text) { var json = Encoding.UTF8.GetString(buffer, 0, result.Count); var myObj = JsonSerializer.Deserialize<MyObj>(json); // 通过事件对外暴露接收的消息(替代Kotlin的Flow) OnMessageReceived?.Invoke(myObj); } else if (result.MessageType == WebSocketMessageType.Close) { await _socket.CloseAsync( WebSocketCloseStatus.NormalClosure, "Closing", CancellationToken.None); } } } catch (Exception ex) { Console.WriteLine(ex.ToString()); } } // 对应Kotlin的closeSession,关闭连接 public async Task CloseSession() { if (_socket?.State == WebSocketState.Open) { await _socket.CloseAsync( WebSocketCloseStatus.NormalClosure, "Client closed session", CancellationToken.None); } _socket?.Dispose(); _socket = null; } // 用于对外暴露接收的消息 public event Action<MyObj>? OnMessageReceived; } // 与Kotlin端结构一致的MyObj类 public class MyObj { // 示例属性,根据实际需求调整 public string? Content { get; set; } public string? Sender { get; set; } }
补充说明
- 如果你的C#环境是Unity或其他特殊平台,可能需要使用对应平台的WebSocket实现(比如Unity的
WebSocket类),但核心逻辑一致:实例化对象→发起连接→发送消息→监听消息→关闭连接。 - 你最初的代码中协议参数传了空字符串,只要Ktor服务器没有要求特定的子协议,这个是没问题的;如果服务器有指定,需要在实例化WebSocket时传入对应协议名称。
内容的提问来源于stack exchange,提问作者AccountForWorks
相关产品推荐
相关产品推荐

