Io go websockets eof

Io go websockets eof,io,websocket,go,eof,Io,Websocket,Go,Eof,我正在尝试制作一个简单的命令转发器,将我的家庭计算机连接到我自己的服务器上,这样我就可以将命令推送到我的服务器上,我的家庭电脑就可以得到它。这些命令对于我的下载程序来说是简单的暂停/恢复。我的设计是,在服务器上,我运行一个hub实例,它创建一个用于传递命令的窗口和一个用于后端将这些命令传递到我的pc的窗口。我用一个通道将这两个“窗口”绑定起来,它们运行一个服务器。当客户端连接并向集线器发送消息时,它会通过一个通道流式传输到后端窗口,然后流式传输到真正的后端(在我的家用电脑上)。当后端响应中心上的

我正在尝试制作一个简单的命令转发器,将我的家庭计算机连接到我自己的服务器上,这样我就可以将命令推送到我的服务器上,我的家庭电脑就可以得到它。这些命令对于我的下载程序来说是简单的暂停/恢复。我的设计是,在服务器上,我运行一个hub实例,它创建一个用于传递命令的窗口和一个用于后端将这些命令传递到我的pc的窗口。我用一个通道将这两个“窗口”绑定起来,它们运行一个服务器。当客户端连接并向集线器发送消息时,它会通过一个通道流式传输到后端窗口,然后流式传输到真正的后端(在我的家用电脑上)。当后端响应中心上的后端窗口时,中心将结果打印回客户端

使用这种方法,只有第一条消息通过并与我的下载程序一起工作。每次收到消息时,我都必须将家用电脑的后端与集线器重新连接,以使其正常工作。我认为这不是WebSocket的正确方法,所以我来了。在一个成功的请求之后(当后端完成它的工作并回复结果时),它将永远循环,并出现EOF错误

守则的重要部分包括:

如果将源代码放在GOPATH中(我正在为go的tip版本开发它,以支持现代WebSocket),编译它:
转到build gosab/cmd
,运行它:

  • /cmd-mode=“hub”
    hub
  • /cmd-mode=“backend”--address=“localhost:8082”
    后端
要将消息传递到中心,请使用以下javascript:

var s = new WebSocket("ws://localhost:8082")
s.send("1 5")

那我该怎么处理呢?频道是两个不同请求之间沟通的好方法吗?

我很惊讶你没有收到这个问题的答案

您需要做的是下面的代码。当您收到传入的websocket连接时,会为该连接生成一个新的goroutine。如果让该goroutine结束,它将断开websocket客户端的连接

我假设您不一定要在同一台计算机上运行客户机和服务器。如果您总是这样,那么最好通过通道等内部通信,而不是使用WebSocket或网络端口。我之所以提到这一点,是因为我不完全确定你用它做什么。我只希望我回答了你问题的正确部分

package main

import (
    "code.google.com/p/go.net/websocket"
    "flag"
    "fmt"
    "net/http"
    "os"
    "time"
)

type Message struct {
    RequestID      int
    Command        string
    SomeOtherThing string
    Success        bool
}

var mode *string = flag.String("mode", "<nil>", "Mode: server or client")
var address *string = flag.String("address", "localhost:8080", "Bind address:port")

func main() {
    flag.Parse()

    switch *mode {
    case "server":
        RunServer()
    case "client":
        RunClient()
    default:
        flag.Usage()
    }
}

func RunServer() {
    http.Handle("/", http.FileServer(http.Dir("www")))
    http.Handle("/server", websocket.Handler(WSHandler))
    fmt.Println("Starting Server")
    err := http.ListenAndServe(*address, nil)
    if err != nil {
        fmt.Printf("HTTP failed: %s\n", err.Error())
        os.Exit(1)
    }
}

func WSHandler(ws *websocket.Conn) {
    defer ws.Close()
    fmt.Println("Client Connected")
    for {
        var message Message
        err := websocket.JSON.Receive(ws, &message)
        if err != nil {
            fmt.Printf("Error: %s\n", err.Error())
            return
        }
        fmt.Println(message)

        // do something useful here...

        response := new(Message)
        response.RequestID = message.RequestID
        response.Success = true
        response.SomeOtherThing = "The hot dog left the castle as requested."
        err = websocket.JSON.Send(ws, response)
        if err != nil {
            fmt.Printf("Send failed: %s\n", err.Error())
            os.Exit(1)
        }
    }
}

func RunClient() {
    fmt.Println("Starting Client")
    ws, err := websocket.Dial(fmt.Sprintf("ws://%s/server", *address), "", fmt.Sprintf("http://%s/", *address))
    if err != nil {
        fmt.Printf("Dial failed: %s\n", err.Error())
        os.Exit(1)
    }
    incomingMessages := make(chan Message)
    go readClientMessages(ws, incomingMessages)
    i := 0
    for {
        select {
        case <-time.After(time.Duration(2e9)):
            i++
            response := new(Message)
            response.RequestID = i
            response.Command = "Eject the hot dog."
            err = websocket.JSON.Send(ws, response)
            if err != nil {
                fmt.Printf("Send failed: %s\n", err.Error())
                os.Exit(1)
            }
        case message := <-incomingMessages:
            fmt.Println(message)
        }
    }
}

func readClientMessages(ws *websocket.Conn, incomingMessages chan Message) {
    for {
        var message Message
        err := websocket.JSON.Receive(ws, &message)
        if err != nil {
            fmt.Printf("Error: %s\n", err.Error())
            return
        }
        incomingMessages <- message
    }
}
主程序包
进口(
“code.google.com/p/go.net/websocket”
“旗帜”
“fmt”
“net/http”
“操作系统”
“时间”
)
类型消息结构{
请求ID int
命令字符串
其他东西串
成功布尔
}
var mode*string=flag.string(“模式”,“模式:服务器或客户端”)
var address*string=flag.string(“地址”、“本地主机:8080”、“绑定地址:端口”)
func main(){
flag.Parse()
开关*模式{
案例“服务器”:
RunServer()
案例“客户”:
RunClient()
违约:
flag.Usage()
}
}
func RunServer(){
http.Handle(“/”,http.FileServer(http.Dir(“www”))
Handle(“/server”,websocket.Handler(WSHandler))
fmt.Println(“启动服务器”)
错误:=http.ListenAndServe(*地址,无)
如果错误!=零{
fmt.Printf(“HTTP失败:%s\n”,err.Error())
操作系统退出(1)
}
}
func WSHandler(ws*websocket.Conn){
延迟ws.Close()
fmt.Println(“客户连接”)
为了{
var消息
err:=websocket.JSON.Receive(ws,&message)
如果错误!=零{
fmt.Printf(“错误:%s\n”,err.Error())
返回
}
fmt.Println(信息)
//在这里做一些有用的事情。。。
响应:=新的(消息)
response.RequestID=message.RequestID
回答:成功=true
response.SomeOtherThing=“热狗按要求离开了城堡。”
err=websocket.JSON.Send(ws,response)
如果错误!=零{
fmt.Printf(“发送失败:%s\n”,err.Error())
操作系统退出(1)
}
}
}
func RunClient(){
fmt.Println(“启动客户”)
ws,err:=websocket.Dial(fmt.Sprintf(“ws://%s/server”,*地址),”,fmt.Sprintf(“http://%s/”,*地址))
如果错误!=零{
fmt.Printf(“拨号失败:%s\n”,err.Error())
操作系统退出(1)
}
incomingMessages:=make(chan消息)
转到readClientMessages(ws,incomingMessages)
i:=0
为了{
挑选{

case重新发明轮子,也许是为了好玩?听起来很像Salt:或Puppet Labs木偶网:很好的链接,但我想自己实现类似的东西。我使用类似的东西(在WebSocket中使用浏览器服务器通信的游戏服务器),所以我知道如何在go中实现,但我不明白真正的问题是什么。如果只是“频道是沟通的好方式吗”,答案是肯定的。你想让我把我的websocket go服务器的主代码发布为答案(太大了,无法评论)吗?我觉得你必须做一些非常类似的事情(更简单的是,你不需要为特定桌子上的所有玩家更新游戏(玩家坐在那里玩或观察))。很抱歉不活动,我真正的问题是,当您将消息传递给代理时,问题是如何将消息传递给另一个websocket连接(此处为后端)。我认为频道不适合这里,不可阻止的队列会更好。我已经在node.js中用浏览器和ruby on后端实现了这个逻辑,所有这些都使用了Faye,所以我不再需要这个问题的答案。我将不得不在基于队列的消息中继中重新实现这个go代码,但从那以后我就没有时间了有很多这样的通信引擎非常有前途,一个简单的事件驱动服务器。我会在有时间的时候尝试这个想法,同时:+1尝试帮助如果你不想关闭连接,为什么你
返回
如果遇到错误,应该终止连接信号上的EOF?