websocket实现go(server)与c#(client)通讯

go 服务端

使用到github.com/gorilla/websocket

go 复制代码
package main

import (
	"fmt"
	"github.com/gorilla/websocket"
	"log"
	"net/http"
)

func main() {
	var upgrader = websocket.Upgrader{
		ReadBufferSize:  1024,
		WriteBufferSize: 1024,
		CheckOrigin: func(r *http.Request) bool {
			return true //允许跨域
		},
	}
	http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) { //将所有的请求转换为websocket
		upgrader.CheckOrigin = func(r *http.Request) bool {
			return true
		}
		conn, err := upgrader.Upgrade(writer, request, nil)
		if err != nil {
			log.Fatal(err)
		}
		for {
			t, msg, err := conn.ReadMessage()
			if err != nil {
				fmt.Printf("read error:%v\n", err)
				break
			}
			fmt.Printf("[ws]recv count:%d recv:%s,msg type:%d\n", len(msg), string(msg), t)
		}
	})

	err := http.ListenAndServe("127.0.0.1:8081", nil)
	if err != nil {
		log.Fatal(err)
	}
}

C#客户端

C#操作websocket当客户端使用时使用System.Net.Websockets这个命名空间下的ClientWebSocket

winform的设计界面如下:

代码如下:

csharp 复制代码
public partial class Form1 : Form
    {
        CancellationTokenSource tokenSource = new CancellationTokenSource();
        System.Net.WebSockets.ClientWebSocket client = new System.Net.WebSockets.ClientWebSocket();
        public Form1()
        {
            InitializeComponent();
            
        }

        private async void button1_Click(object sender, EventArgs e)
        {
            try
            {
                var content=this.rtbContent.Text;
                if (string.IsNullOrEmpty(content))
                {
                    MessageBox.Show("请输入内容来发送");
                    return;
                }
                if (client.State != System.Net.WebSockets.WebSocketState.Open)
                {
                    tokenSource = new CancellationTokenSource();
                    client = new System.Net.WebSockets.ClientWebSocket();
                    //client.Options.KeepAliveInterval = TimeSpan.FromSeconds(1);
                    await client.ConnectAsync(new Uri("ws://127.0.0.1:8081"), tokenSource.Token);
                    var bytes = new byte[10240];
                    var array = new ArraySegment<byte>(bytes);
                    Task.Factory.StartNew(async () =>
                    {
                        while (true)
                        {
                            try
                            {
                                var msg = await client.ReceiveAsync(array, tokenSource.Token);
                            }
                            catch (Exception ex)
                            {
                                MessageBox.Show(ex.Message);
                                tokenSource.Cancel();
                                return;
                            }
                        }
                    });
                }
                var buffer = Encoding.UTF8.GetBytes(content);
                await client.SendAsync(new ArraySegment<byte>(buffer), System.Net.WebSockets.WebSocketMessageType.Text, true, tokenSource.Token);
                MessageBox.Show($"已发送{buffer.Length}个字节");
            }
            catch (Exception ee)
            {
                MessageBox.Show(ee.ToString());
            }
        }
    }

注意:无论是客户端断开还是服务端断开,如果正在读取消息,则会触发错误。利用此机制可以很方便的处理重连问题。

相关推荐
Eiceblue1 小时前
使用 C# 将 Excel 转换为 Markdown 表格(含批量转换示例)
开发语言·c#·excel
lolo大魔王3 小时前
Go语言的并发、协调创建和通信机制
开发语言·golang
不会编程的懒洋洋3 小时前
WPF XAML+布局+控件
xml·开发语言·c#·视觉检测·wpf·机器视觉·视图
唐青枫4 小时前
别再层层传参了!C#.NET AsyncLocal 异步上下文透传实战
c#·.net
geovindu4 小时前
go:Template Method Pattern
开发语言·后端·设计模式·golang·模板方法模式
怪我冷i4 小时前
多租户管理系统,用户表,IsSuperAdmin,IsTenantAdmin,IsCompanyAdmin,IsDeptAdmin需要吗?
golang·llm·多租户·skill
明如正午5 小时前
【C#】托管调试助手 “PInvokeStackImbalance“:的调用导致堆栈不对称。原因可能是托管的 PInvoke 签名与非托管的目标签名不匹配。
c#
垦利不5 小时前
websocket通信
网络·websocket·网络协议
Eiceblue5 小时前
C# 如何实现 Word 转 Excel ?分享两种实用方法
c#·word·excel