Go Client Connect to an URL with Socket

huangapple go评论91阅读模式
英文:

Go Client Connect to an URL with Socket

问题

我是你的中文翻译助手,以下是翻译好的内容:

我是Go的新手。我有一个运行FastAPI Python的服务器。我已经在127.0.0.1:8000/register上运行了WebSocket请求。

@app.websocket("/register")
async def websocket_endpoint(websocket: WebSocket):
    await websocket.accept()
    while True:
        data = await websocket.receive_text()
        await websocket.send_text(f"Message text was: {data}")

我想创建一个作为客户端的应用程序,使用Go语言连接到这个URL并发送信息以创建账户。但是当我尝试在Google上使用示例代码时,出现了以下错误:

package main

import (
    "net"
    "fmt"
    "bufio"
    "os"
    "log"
)

func main() {
    // 连接服务器
    conn, err := net.Dial("tcp", "127.0.0.1:8000/register")
    if err != nil {
        log.Println(err)
    }
    for {
        // 要发送什么?
        reader := bufio.NewReader(os.Stdin)
        fmt.Print("Text to send: ")
        text, err := reader.ReadString('\n')
        if err != nil {
            log.Println(err)
        }
        // 发送到服务器
        fmt.Fprintf(conn, text + "\n")
        // 等待回复
        message, err := bufio.NewReader(conn).ReadString('\n')
        if err != nil {
            log.Println(err)
        }
        fmt.Print("Message from server: " + message)
    }
}

由于dial tcp: lookup tcp/8000/register: getaddrinfow: The specified class was not found,它无法正常工作。

据我了解,它无法查找此链接,它只能在IP地址时进行查找。我该如何创建一个到URL的Socket请求?

英文:

I'm newbie in Go. I have a server run FastAPI Python. I have already run websocket request in 127.0.0.1:8000/register.

@app.websocket("/register")
async def websocket_endpoint(websocket: WebSocket):
    await websocket.accept()
    while True:
        data = await websocket.receive_text()
        await websocket.send_text(f"Message text was: {data}")

I want to create an app work as a client by Go. This app use socket connect to this URL and send info to create account. But when I try to use example code in google:

package main

import "net"
import "fmt"
import "bufio"
import "os"
import "log"

func main() {
  // connect to server
  conn, err := net.Dial("tcp", "127.0.0.1:8000/register")
  if err != nil {
    log.Println(err)
}
  for { 
    // what to send?
    reader := bufio.NewReader(os.Stdin)
    fmt.Print("Text to send: ")
    text, err := reader.ReadString('\n')
    if err != nil {
        log.Println(err)
    }
    // send to server
    fmt.Fprintf(conn, text + "\n")
    // wait for reply
    message, err := bufio.NewReader(conn).ReadString('\n')
    if err != nil {
        log.Println(err)
    }
    fmt.Print("Message from server: "+message)
  }
}

It's not working because of dial tcp: lookup tcp/8000/register: getaddrinfow: The specified class was not found

As I understand that it cannot lookup for this link, it only lookups when it's a IP Address.
How can I create a Socket request to an URL?

答案1

得分: 1

使用github.com/gorilla/websocket包可以在Go语言中实现WebSocket功能。下面是一个示例代码:

package main

import (
	"flag"
	"log"
	"net/url"
	"os"
	"os/signal"
	"time"

	"github.com/gorilla/websocket"
)

var addr = flag.String("addr", "127.0.0.1:8080", "http service address")

func main() {
	flag.Parse()
	log.SetFlags(0)

	interrupt := make(chan os.Signal, 1)
	signal.Notify(interrupt, os.Interrupt)

	u := url.URL{Scheme: "ws", Host: *addr, Path: "/register"}
	log.Printf("connecting to %s", u.String())

	c, _, err := websocket.DefaultDialer.Dial(u.String(), nil)
	if err != nil {
		log.Fatal("dial:", err)
	}
	defer c.Close()

	done := make(chan struct{})

	go func() {
		defer close(done)
		for {
			_, message, err := c.ReadMessage()
			if err != nil {
				log.Println("read:", err)
				return
			}
			log.Printf("recv: %s", message)
		}
	}()

	ticker := time.NewTicker(time.Second)
	defer ticker.Stop()

	for {
		select {
		case <-done:
			return
		case t := <-ticker.C:
			err := c.WriteMessage(websocket.TextMessage, []byte(t.String()))
			if err != nil {
				log.Println("write:", err)
				return
			}
		case <-interrupt:
			log.Println("interrupt")

			// Cleanly close the connection by sending a close message and then
			// waiting (with timeout) for the server to close the connection.
			err := c.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, ""))
			if err != nil {
				log.Println("write close:", err)
				return
			}
			select {
			case <-done:
			case <-time.After(time.Second):
			}
			return
		}
	}
}

另外,nhooyr.io/websocket是一个用于Go语言的最小化和符合惯例的WebSocket库。以下是一个示例代码:

ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
defer cancel()

c, _, err := websocket.Dial(ctx, "ws://localhost:8080/register", nil)
if err != nil {
	// ...
}
defer c.Close(websocket.StatusInternalError, "the sky is falling")

你可以在https://github.com/nhooyr/websocket上找到更多关于nhooyr.io/websocket的信息。

英文:

use github.com/gorilla/websocket
example:

package main

import (
	&quot;flag&quot;
	&quot;log&quot;
	&quot;net/url&quot;
	&quot;os&quot;
	&quot;os/signal&quot;
	&quot;time&quot;

	&quot;github.com/gorilla/websocket&quot;
)

var addr = flag.String(&quot;addr&quot;, &quot;127.0.0.1:8080&quot;, &quot;http service address&quot;)

func main() {
	flag.Parse()
	log.SetFlags(0)

	interrupt := make(chan os.Signal, 1)
	signal.Notify(interrupt, os.Interrupt)

	u := url.URL{Scheme: &quot;ws&quot;, Host: *addr, Path: &quot;/register&quot;}
	log.Printf(&quot;connecting to %s&quot;, u.String())

	c, _, err := websocket.DefaultDialer.Dial(u.String(), nil)
	if err != nil {
		log.Fatal(&quot;dial:&quot;, err)
	}
	defer c.Close()

	done := make(chan struct{})

	go func() {
		defer close(done)
		for {
			_, message, err := c.ReadMessage()
			if err != nil {
				log.Println(&quot;read:&quot;, err)
				return
			}
			log.Printf(&quot;recv: %s&quot;, message)
		}
	}()

	ticker := time.NewTicker(time.Second)
	defer ticker.Stop()

	for {
		select {
		case &lt;-done:
			return
		case t := &lt;-ticker.C:
			err := c.WriteMessage(websocket.TextMessage, []byte(t.String()))
			if err != nil {
				log.Println(&quot;write:&quot;, err)
				return
			}
		case &lt;-interrupt:
			log.Println(&quot;interrupt&quot;)

			// Cleanly close the connection by sending a close message and then
			// waiting (with timeout) for the server to close the connection.
			err := c.WriteMessage(websocket.CloseMessage, websocket.FormatCloseMessage(websocket.CloseNormalClosure, &quot;&quot;))
			if err != nil {
				log.Println(&quot;write close:&quot;, err)
				return
			}
			select {
			case &lt;-done:
			case &lt;-time.After(time.Second):
			}
			return
		}
	}
}

or nhooyr.io/websocket - is a minimal and idiomatic WebSocket library for Go
https://github.com/nhooyr/websocket

ctx, cancel := context.WithTimeout(context.Background(), time.Minute)
defer cancel()

c, _, err := websocket.Dial(ctx, &quot;ws://localhost:8080/register&quot;, nil)
if err != nil {
	// ...
}
defer c.Close(websocket.StatusInternalError, &quot;the sky is falling&quot;)

huangapple
  • 本文由 发表于 2021年10月21日 10:22:22
  • 转载请务必保留本文链接:https://go.coder-hub.com/69655088.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定