иди в сеть - PullRequest
       29

иди в сеть

6 голосов
/ 16 февраля 2012

Я пытаюсь сделать простой перенаправитель команд для подключения моего домашнего компьютера к серверу, которым я владею, чтобы я мог передавать команды на свой сервер, и мой домашний компьютер получает его.Эти команды - простая пауза / возобновление для моего загрузчика.Мой дизайн таков, что на сервере я запускаю экземпляр концентратора, который создает окно для передачи команд и окно для бэкэнда, чтобы передавать эти команды моему компьютеру.Я связываю эти два «окна» с каналом, они запускают сервер.Когда клиент подключается и отправляет сообщение в концентратор, он передается через канал в окно бэкэнда, а затем в реальный бэкэнд (на моем домашнем компьютере).Когда бэкэнд отвечает на окно бэкенда на хабе, хаб выводит результат обратно клиенту.

При таком подходе только первое сообщение проходит и работает с моим загрузчиком.Я должен переподключать серверную часть своего домашнего компьютера к концентратору каждый раз, когда получаю сообщение, чтобы это работало должным образом.Я не думаю, что это правильно с веб-сокетами, так что вот и я.После одного успешного запроса (когда бэкэнд завершает свою работу и отвечает на результат), он зацикливается навсегда с ошибкой EOF.

Важными частями кода являются:

Если вы поместите источник в свойGOPATH (я разрабатываю его для конечной версии go для поддержки современных веб-сокетов), чтобы скомпилировать его: go build gosab/cmd, запустить его:

  • ./cmd -mode="hub" hub
  • ./cmd -mode="backend" --address="localhost:8082" backend

Для передачи сообщений в концентратор используйте этот javascript:

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

Так как мне обращатьсяЭто?Являются ли каналы хорошим способом связи между двумя разными запросами?

1 Ответ

7 голосов
/ 18 мая 2012

Я удивлен, что вы не получили ответа на этот вопрос.

Что вам нужно сделать, это что-то вроде кода ниже. Когда вы получаете входящее соединение через веб-сокет, для этого соединения создается новая программа. Если вы дадите конец этой программе, он отключит клиент 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
    }
}
...