go-socket.io 无效的传输方式

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

go-socket.io invalid transport

问题

我正在尝试使用go-socket.io库来构建一个使用golang的在线聊天应用程序,所以我按照文档中的示例创建了一个简单的结构。

我的main.go文件如下所示:

package main

import (
	"log"
	"net/http"

	"github.com/gin-gonic/gin"

	socketio "github.com/googollee/go-socket.io"
)

func GinMiddleware(allowOrigin string) gin.HandlerFunc {
	return func(c *gin.Context) {
		c.Writer.Header().Set("Access-Control-Allow-Origin", allowOrigin)
		c.Writer.Header().Set("Access-Control-Allow-Credentials", "true")
		c.Writer.Header().Set("Access-Control-Allow-Methods", "POST, OPTIONS, GET, PUT, DELETE")
		c.Writer.Header().Set("Access-Control-Allow-Headers", "Accept, Authorization, Content-Type, Content-Length, X-CSRF-Token, Token, session, Origin, Host, Connection, Accept-Encoding, Accept-Language, X-Requested-With")

		if c.Request.Method == http.MethodOptions {
			c.AbortWithStatus(http.StatusNoContent)
			return
		}

		c.Request.Header.Del("Origin")

		c.Next()
	}
}

func main() {
	router := gin.New()

	server := socketio.NewServer(nil)

	server.OnConnect("/", func(s socketio.Conn) error {
		s.SetContext("")
		log.Println("connected:", s.ID())
		return nil
	})

	server.OnEvent("/", "notice", func(s socketio.Conn, msg string) {
		log.Println("notice:", msg)
		s.Emit("reply", "have "+msg)
	})

	server.OnEvent("/chat", "msg", func(s socketio.Conn, msg string) string {
		s.SetContext(msg)
		return "recv " + msg
	})

	server.OnEvent("/", "bye", func(s socketio.Conn) string {
		last := s.Context().(string)
		s.Emit("bye", last)
		s.Close()
		return last
	})

	server.OnError("/", func(s socketio.Conn, e error) {
		log.Println("meet error:", e)
	})

	server.OnDisconnect("/", func(s socketio.Conn, msg string) {
		log.Println("closed", msg)
	})

	go func() {
		if err := server.Serve(); err != nil {
			log.Fatalf("socketio listen error: %s\n", err)
		}
	}()
	defer server.Close()

	router.Use(GinMiddleware("http://localhost:3000"))
	router.GET("/socket.io/*any", gin.WrapH(server))
	router.POST("/socket.io/*any", gin.WrapH(server))
	router.StaticFS("/public", http.Dir("../asset/index.html"))

	if err := router.Run(":8000"); err != nil {
		log.Fatal("failed run app: ", err)
	}
}

我的前端代码如下所示:

<!doctype html>
<html>
  <head>
    <title>Socket.IO chat</title>
    <style>
      * { margin: 0; padding: 0; box-sizing: border-box; }
      body { font: 13px Helvetica, Arial; }
      form { background: #000; padding: 3px; position: fixed; bottom: 0; width: 100%; }
      form input { border: 0; padding: 10px; width: 90%; margin-right: .5%; }
      form button { width: 9%; background: rgb(130, 224, 255); border: none; padding: 10px; }
      #messages { list-style-type: none; margin: 0; padding: 0; }
      #messages li { padding: 5px 10px; }
      #messages li:nth-child(odd) { background: #eee; }
    </style>
  </head>
  <body>
    <ul id="messages"></ul>
    <form action="">
      <input id="m" autocomplete="off" /><button>Send</button>
    </form>
    <script src="https://cdn.socket.io/socket.io-1.4.5.js"></script>
    <script src="https://code.jquery.com/jquery-1.11.1.js"></script>
    <script>
      var socket = io();
      var s2 = io("/chat");

      socket.on('reply', function(msg){
        $('#messages').append($('<li>').text(msg));
      });

      $('form').submit(function(){
        s2.emit('msg', $('#m').val(), function(data){
          $('#messages').append($('<li>').text('ACK CALLBACK: ' + data));
        });

        socket.emit('notice', $('#m').val());

        $('#m').val('');
        return false;
      });
    </script>
  </body>
</html>

但是当我在浏览器中运行代码,访问URL:http://localhost:8000/socket.io/ 时,我收到以下错误信息:

invalid transport: %!s(<nil>)

为什么会出现这个错误?我尝试了一些来自以下网站的提示:

https://socket.io/docs/v3/troubleshooting-connection-issues/

但是没有任何方法对我有帮助。

英文:

I'm trying to use the go-socket.io library to build an online chat with golang
so I made a simple structure, following the examples in the documentation

my main.go looks like this:

package main

import (
	&quot;log&quot;
	&quot;net/http&quot;

	&quot;github.com/gin-gonic/gin&quot;

	socketio &quot;github.com/googollee/go-socket.io&quot;
)

func GinMiddleware(allowOrigin string) gin.HandlerFunc {
	return func(c *gin.Context) {
		c.Writer.Header().Set(&quot;Access-Control-Allow-Origin&quot;, allowOrigin)
		c.Writer.Header().Set(&quot;Access-Control-Allow-Credentials&quot;, &quot;true&quot;)
		c.Writer.Header().Set(&quot;Access-Control-Allow-Methods&quot;, &quot;POST, OPTIONS, GET, PUT, DELETE&quot;)
		c.Writer.Header().Set(&quot;Access-Control-Allow-Headers&quot;, &quot;Accept, Authorization, Content-Type, Content-Length, X-CSRF-Token, Token, session, Origin, Host, Connection, Accept-Encoding, Accept-Language, X-Requested-With&quot;)

		if c.Request.Method == http.MethodOptions {
			c.AbortWithStatus(http.StatusNoContent)
			return
		}

		c.Request.Header.Del(&quot;Origin&quot;)

		c.Next()
	}
}

func main() {
	router := gin.New()

	server := socketio.NewServer(nil)

	server.OnConnect(&quot;/&quot;, func(s socketio.Conn) error {
		s.SetContext(&quot;&quot;)
		log.Println(&quot;connected:&quot;, s.ID())
		return nil
	})

	server.OnEvent(&quot;/&quot;, &quot;notice&quot;, func(s socketio.Conn, msg string) {
		log.Println(&quot;notice:&quot;, msg)
		s.Emit(&quot;reply&quot;, &quot;have &quot;+msg)
	})

	server.OnEvent(&quot;/chat&quot;, &quot;msg&quot;, func(s socketio.Conn, msg string) string {
		s.SetContext(msg)
		return &quot;recv &quot; + msg
	})

	server.OnEvent(&quot;/&quot;, &quot;bye&quot;, func(s socketio.Conn) string {
		last := s.Context().(string)
		s.Emit(&quot;bye&quot;, last)
		s.Close()
		return last
	})

	server.OnError(&quot;/&quot;, func(s socketio.Conn, e error) {
		log.Println(&quot;meet error:&quot;, e)
	})

	server.OnDisconnect(&quot;/&quot;, func(s socketio.Conn, msg string) {
		log.Println(&quot;closed&quot;, msg)
	})

	go func() {
		if err := server.Serve(); err != nil {
			log.Fatalf(&quot;socketio listen error: %s\n&quot;, err)
		}
	}()
	defer server.Close()

	router.Use(GinMiddleware(&quot;http://localhost:3000&quot;))
	router.GET(&quot;/socket.io/*any&quot;, gin.WrapH(server))
	router.POST(&quot;/socket.io/*any&quot;, gin.WrapH(server))
	router.StaticFS(&quot;/public&quot;, http.Dir(&quot;../asset/index.html&quot;))

	if err := router.Run(&quot;:8000&quot;); err != nil {
		log.Fatal(&quot;failed run app: &quot;, err)
	}
}

my front end looks like this:

<!-- begin snippet: js hide: false console: true babel: false -->

<!-- language: lang-html -->

&lt;!doctype html&gt;
&lt;html&gt;
&lt;head&gt;
&lt;title&gt;Socket.IO chat&lt;/title&gt;
&lt;style&gt;
* { margin: 0; padding: 0; box-sizing: border-box; }
body { font: 13px Helvetica, Arial; }
form { background: #000; padding: 3px; position: fixed; bottom: 0; width: 100%; }
form input { border: 0; padding: 10px; width: 90%; margin-right: .5%; }
form button { width: 9%; background: rgb(130, 224, 255); border: none; padding: 10px; }
#messages { list-style-type: none; margin: 0; padding: 0; }
#messages li { padding: 5px 10px; }
#messages li:nth-child(odd) { background: #eee; }
&lt;/style&gt;
&lt;/head&gt;
&lt;body&gt;
&lt;ul id=&quot;messages&quot;&gt;&lt;/ul&gt;
&lt;form action=&quot;&quot;&gt;
&lt;input id=&quot;m&quot; autocomplete=&quot;off&quot; /&gt;&lt;button&gt;Send&lt;/button&gt;
&lt;/form&gt;
&lt;script src=&quot;https://cdn.socket.io/socket.io-1.4.5.js&quot;&gt;&lt;/script&gt;
&lt;script src=&quot;https://code.jquery.com/jquery-1.11.1.js&quot;&gt;&lt;/script&gt;
&lt;script&gt;
var socket = io();
var s2 = io(&quot;/chat&quot;);
socket.on(&#39;reply&#39;, function(msg){
$(&#39;#messages&#39;).append($(&#39;&lt;li&gt;&#39;).text(msg));
});
$(&#39;form&#39;).submit(function(){
s2.emit(&#39;msg&#39;, $(&#39;#m&#39;).val(), function(data){
$(&#39;#messages&#39;).append($(&#39;&lt;li&gt;&#39;).text(&#39;ACK CALLBACK: &#39; + data));
});
socket.emit(&#39;notice&#39;, $(&#39;#m&#39;).val());
$(&#39;#m&#39;).val(&#39;&#39;);
return false;
});
&lt;/script&gt;
&lt;/body&gt;
&lt;/html&gt;

<!-- end snippet -->

but when running the code in the browser, by the url: http://localhost:8000/socket.io/
i get this error:

invalid transport: %!s(&lt;nil&gt;)

why?
I tried to use some tips from this site:

https://socket.io/docs/v3/troubleshooting-connection-issues/

but no alternative helped me

答案1

得分: 1

除了@code_monk指出的问题之外,下面的代码也是错误的:

router.StaticFS("/public", http.Dir("../asset/index.html"))

正如其名称所示,http.Dir是一个目录而不是一个文件,所以正确的代码应该是:

router.StaticFS("/public", http.Dir("../asset"))

在浏览器中打开的URL是:http://localhost:8080/public/。


如果你想提供单个文件,可以使用StaticFile

router.StaticFile("/", "../asset/index.html")

在浏览器中打开的URL是:http://localhost:8080/。


还要注意../asset。也许你的意思是./asset(取决于你的文件目录结构)。

英文:

Besides the issue pointed out by @code_monk, the following code is incorrect too:

router.StaticFS(&quot;/public&quot;, http.Dir(&quot;../asset/index.html&quot;))

As the name implies, http.Dir is a directory instead of a file, so the correct code should be:

router.StaticFS(&quot;/public&quot;, http.Dir(&quot;../asset&quot;))

And the URL to open in the browser is: http://localhost:8080/public/.


If you want to serve a single file, you can use StaticFile instead:

router.StaticFile(&quot;/&quot;, &quot;../asset/index.html&quot;)

And the URL to open in the browser is: http://localhost:8080/.


Pay attention to ../asset too. Maybe you mean ./asset (depends on the directory structure of your files).

huangapple
  • 本文由 发表于 2023年7月27日 21:51:26
  • 转载请务必保留本文链接:https://go.coder-hub.com/76780437.html
匿名

发表评论

匿名网友

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

确定