Gorilla Websocket没有收到消息

约翰

我正在Golang中建立一个与Gorilla websockets通信的网关。

我正在Ubuntu 16.04上运行它,并正在使用.NET控制台应用程序对其进行测试。

在Windows上使用Wireshark和在Ubuntu上使用sniffit已确定消息已从Windows客户端正确发送并由Ubuntu盒子接收

但是,在我的代码中,有时在几次成功的消息之后,有时甚至一无所获,我的网关无法读取消息(仍然位于_, msg, errCon := conn.ReadMessage()

输出示例如下:

2018/03/27 02:38:06等待消息... 2018/03/27 02:38:07收到消息:main.AdminRequest {Data:“ {\” SomeDataHeader \“:\” SomeData \“}”,请求者:“用户”,类型:“ JustDoSomethingRequest”,Ukey:“ talca”} 2018/03/27 02:38:07 {“ SomeDataHeader”:“ SomeData”} 2018/03/27 02:38:07等待消息。 ..

就像我之前说过的那样,它可能会收到一些这样的消息,但是,尽管两端的网络流量仍在继续,但是不会再收到任何消息。

我对Golang相当陌生,并且在我缺少某些东西的前提下工作。

为了简洁起见,我在下面的代码中整理了错误处理等内容,但这是失败代码的示例。

编辑根据要求,我在下面添加了Golang完整代码和C#客户端代码(尽管正如我所说,Wireshark和sniffit已确定数据正在传输)

package main

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

var upgrader = websocket.Upgrader{ ReadBufferSize:  1024, WriteBufferSize: 1024,
    CheckOrigin: func(r *http.Request) bool {
        return true
    },
}

type AdminRequest struct {
        Data      string `json:"Data"`
        Requestor string `json:"Requestor"`
        Type      string `json:"Type"`
        Ukey      string `json:"Ukey"`
    } 

func main() {

    http.HandleFunc("/a", func(w http.ResponseWriter, r *http.Request) {
        var conn, _ = upgrader.Upgrade(w, r, nil)

        go func(conn *websocket.Conn) {
            for {
                _, _, err := conn.ReadMessage()
                if err != nil {         
                    log.Println("Close: "+ err.Error())
                    conn.Close()
                    return
                }
            }
        }(conn)


        go func(conn *websocket.Conn) {
            for {

                log.Println("Awaiting Message ...")
                _, msg, errCon := conn.ReadMessage()

                if errCon != nil {
                    log.Println("Read Error:", errCon)
                    break
                }

                log.Println("Message received: ")

                var r AdminRequest

                if err := json.Unmarshal(msg, &r); err != nil {

                    log.Println("Error: " + err.Error());
                    return;
                }

                fmt.Printf("%#v\n", r)
                log.Println(r.Data);
            }           
        }(conn)

    })

    http.ListenAndServe(":3000", nil)
}

C#代码:

public class Client : IDisposable
    {
        private ClientWebSocket _socket;


        string _address;
        int _port;
        public Client(string address)
        {
            _address = address;

            _socket = new ClientWebSocket();
        }

        public async void SetupForReceivingStuffs()
        {
            while (_socket.State == WebSocketState.Open)
            {
                ArraySegment<byte> receivedBytes = new ArraySegment<byte>(new byte[1024]);
                WebSocketReceiveResult result = await _socket.ReceiveAsync(receivedBytes, CancellationToken.None);

                Console.WriteLine(Encoding.UTF8.GetString(receivedBytes.Array, 0, result.Count));
            }
        }

        public async void SetupForSendingStuffs(ConcurrentQueue<AdminRequest> queue)
        {
            while (_socket.State == WebSocketState.Open)
            {
                AdminRequest next;

                while (queue.Count > 0)
                {
                    if (queue.TryDequeue(out next))
                    {
                        await Send(next);
                    }
                }

                await Task.Yield();
            }
        }

        public async Task Connect()
        {
            while (_socket.State != WebSocketState.Open)
            {
                try
                {
                    _socket = new ClientWebSocket();
                    await _socket.ConnectAsync(new Uri(_address), CancellationToken.None);

                    Console.WriteLine("Socket state: " + _socket.State);
                }
                catch (Exception ex)
                {
                    //Not getting hit
                    Console.WriteLine(ex.Message);
                    Console.WriteLine(ex.StackTrace);
                }
            }
        }



        public Task Send<TData>(TData data)
        {
            string text = JsonConvert.SerializeObject(data);

            var encoded = Encoding.UTF8.GetBytes(text);
            var buffer = new ArraySegment<Byte>(encoded, 0, encoded.Length);

            return _socket.SendAsync(buffer, WebSocketMessageType.Text, true, CancellationToken.None);
        }


        public void Dispose()
        {
            _socket.Dispose();
        }
    }

致电者:

class Program
{
    static ConcurrentQueue<AdminRequest> _toSend;

    static void Main(string[] args)
    {
        _toSend = new ConcurrentQueue<AdminRequest>();

        Client client = new Client("ws:/(myip):(myport)/a");
        client.Connect().Wait();

        //client.SetupForReceivingStuffs();
        client.SetupForSendingStuffs(_toSend);

        WriteInstructions();

        LoopAuto();

        Console.WriteLine("Bye");
    }

    private static void LoopAuto()
    {
        DateTime nextMessage = DateTime.Now;

        while (true)
        {

            if (DateTime.Now < nextMessage) continue;
            Console.WriteLine("Next");
            nextMessage = DateTime.Now.AddSeconds(2);

            _toSend.Enqueue(new AdminRequest
            {
                Data = "{\"SomeDataHeader\":\"SomeData\"}",
                Requestor = "user",
                Type = "JustDoSomethingRequest",
                Ukey = "talca"
            });
        }
    }

    private static ConsoleKeyInfo LoopManual()
    {
        ConsoleKeyInfo info;
        do
        {
            info = Console.ReadKey(true);

            if (info.KeyChar == '1')
            {
                _toSend.Enqueue(new AdminRequest
                {
                    Data = "{\"SomeDataHeader\":\"SomeData\"}",
                    Requestor = "user",
                    Type = "JustDoSomethingRequest",
                    Ukey = "talca"
                });
            }
            else if (info.KeyChar == 'i')
            {
                WriteInstructions();
            }

        } while (info.KeyChar != 'x');

        return info;
    }

    private static void WriteInstructions()
    {
        Console.WriteLine("1. Send New Message");
        Console.WriteLine("i. Instructions (these lines)");
        Console.WriteLine("x: Exit");
    }
}
松饼上衣:

该应用程序运行两个goroutine,它们循环读取消息。第一个对接收到的消息不执行任何操作。第二个解析并记录该消息。您看不到任何输出,因为第一个goroutine正在接收消息。

第一个goroutine似乎没有任何作用。删除第一个goroutine以解决问题。

删除第一个goroutine也会修复数据争用。不支持在websocket连接上并发读取比赛探测器会报告这个问题。

这是具有其他修复和改进功能的更新代码。net / http服务器通过每个连接的goroutine调用处理程序。使用tha goroutine而不是启动另一个goroutine。使用websocket包的JSON帮助器方法。

package main

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

var upgrader = websocket.Upgrader{ ReadBufferSize:  1024, WriteBufferSize: 1024,
    CheckOrigin: func(r *http.Request) bool {
        return true
    },
}

type AdminRequest struct {
        Data      string `json:"Data"`
        Requestor string `json:"Requestor"`
        Type      string `json:"Type"`
        Ukey      string `json:"Ukey"`
    } 

func wsHandler(w http.ResponseWriter, r *http.Request) {
    conn, err := upgrader.Upgrade(w, r, nil)
    if err != nil {
        log.Println(err)
        return
    }
    defer conn.Close()
    for {
        var r AdminRequest
        if err := conn.ReadJSON(&r); err != nil {
            log.Println(err)
            break
        }
        fmt.Printf("%#v\n", r)
        log.Println(r.Data);
    }           
}

func main() {
    http.HandleFunc("/a", wsHandler)
    http.ListenAndServe(":3000", nil)
}

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

TLS上的WebSocket:Golang / Gorilla

gorilla/websocket 设置读取限制?

我没有收到WebSocket消息(SimpMessagingTemplate)

Gorilla WebSocket WriteMessage错误-Go Lang

带有cookie身份验证的Gorilla Websocket

Gorilla WebSocket与golang.org/x/net/websocket的比较

使用Golang的gorilla / websocket软件包的Websocket连接断开

将Websocket消息发送到Go中的特定客户端(使用Gorilla)

将Websocket消息发送到Go中的特定频道(使用Gorilla)

使用Gorilla FormatCloseMessage客户端收到错误的代码

Gorilla Websocket错误:关闭1007 UTF-8非法序列

如何使用Golang Gorilla / mux托管并发Websocket连接?

Golang Gorilla CEX.IO Websocket身份验证错误

Golang Gorilla Websocket在120秒后停止接收信息

使用Gorilla会话自定义后端有什么优势?

Goor中带有Gorilla / rpc的JSON RPC请求

如何在Gorilla Mux中列出所有变量?

没有收到推送消息

没有路由器Gorilla Mux的Google Cloud Go处理程序?

我正在运行 Ubuntu 20.10 Groovy Gorilla。Mysql 包没有安装/更新

Gorilla Websocket:WebSocket握手期间出错:意外的响应代码:404

运行Go应用程序的多个实例时的Gorilla Websocket连接

Gorilla Websocket如何将二进制数据解组为JSON?

一分钟后,Gorilla WebSocket断开连接

ImapIdleChannelAdapter没有收到消息内容

没有收到来自频道的消息

Spring Kafka没有收到消息

BroadcastReceiver没有收到广播事件消息

德尔福线程没有收到消息