WebTransport + Gin example? #81
-
|
Hello, I'm struggling to get WebTransport to work (in general) with my simple gin example. I've tried to read the WebTransport engine.io example but it's not clear how I can set this up on my server. Would love some help on how to get this set up nicely |
Beta Was this translation helpful? Give feedback.
Replies: 8 comments
-
|
The Go WebTransport project is currently in a suspended maintenance state. https://github.com/quic-go/webtransport-go?tab=readme-ov-file#webtransport-go-is-currently-unfunded |
Beta Was this translation helpful? Give feedback.
-
|
thanks @zishang520 - saw that. While that is obviously concerning for the golang ecosystem, I don't think that the webtransport WC3 is heading towards death. In fact there have been tons of contributions in the last year. That being said, because your engine.io lib supports it, does that mean that maybe your socket.io library supports it? Appreciate the help, trying to determine if we move deeper into our organizations investment into socket.io. |
Beta Was this translation helpful? Give feedback.
-
|
Theoretically, it is possible. I haven't written a sample code yet, but I will add test code snippets later. |
Beta Was this translation helpful? Give feedback.
-
|
@zishang520 - I was just talking to my team about this - we would be willing to help fund your efforts if of interest |
Beta Was this translation helpful? Give feedback.
-
|
@bneigher Sorry for the long wait! Since I was on holiday and taking care of my child, who is not yet one year old, I only now have some free time. |
Beta Was this translation helpful? Give feedback.
-
|
other: Use gin(Not necessary) + webtransport package main
import (
"net/http"
"os"
"os/signal"
"syscall"
"time"
"github.com/gin-gonic/gin"
"github.com/zishang520/engine.io/v2/engine"
"github.com/zishang520/engine.io/v2/log"
"github.com/zishang520/engine.io/v2/types"
"github.com/zishang520/engine.io/v2/webtransport"
"github.com/zishang520/socket.io/v2/socket"
)
func main() {
log.DEBUG = true
c := socket.DefaultServerOptions()
c.SetServeClient(true)
// c.SetConnectionStateRecovery(&socket.ConnectionStateRecovery{})
// c.SetAllowEIO3(true)
c.SetPingInterval(300 * time.Millisecond)
c.SetPingTimeout(200 * time.Millisecond)
c.SetMaxHttpBufferSize(1000000)
c.SetConnectTimeout(1000 * time.Millisecond)
c.SetTransports(types.NewSet("polling", "webtransport"))
c.SetCors(&types.Cors{
Origin: "*",
Credentials: true,
})
socketio := socket.NewServer(nil, nil)
socketio.On("connection", func(clients ...interface{}) {
client := clients[0].(*socket.Socket)
client.On("message", func(args ...interface{}) {
client.Emit("message-back", args...)
})
client.Emit("auth", client.Handshake().Auth)
client.On("message-with-ack", func(args ...interface{}) {
ack := args[len(args)-1].(socket.Ack)
ack(args[:len(args)-1], nil)
})
})
socketio.Of("/custom", nil).On("connection", func(clients ...interface{}) {
client := clients[0].(*socket.Socket)
client.Emit("auth", client.Handshake().Auth)
})
app := gin.Default()
// app.Put("/socket.io", adaptor.HTTPHandler(socketio.ServeHandler(c))) // test
app.POST("/socket.io/*f", gin.WrapH(socketio.ServeHandler(c)))
app.GET("/socket.io/*f", gin.WrapH(socketio.ServeHandler(c)))
go app.Run(":8080")
// WebTransport start
// WebTransport uses udp, so you need to enable the new service.
customServer := types.NewWebServer(nil)
// A certificate is required and cannot be a self-signed certificate.
wts := customServer.ListenWebTransportTLS(":443", "domain.cer", "domain.key", nil, nil)
// Here is the core logic of the WebTransport handshake.
customServer.HandleFunc(socketio.Path()+"/", func(w http.ResponseWriter, r *http.Request) {
if webtransport.IsWebTransportUpgrade(r) {
// You need to call socketio.ServeHandler(nil) before this, otherwise you cannot get the Engine instance.
socketio.Engine().(engine.Server).OnWebTransportSession(types.NewHttpContext(w, r), wts)
} else {
customServer.DefaultHandler.ServeHTTP(w, r)
}
})
// WebTransport end
exit := make(chan struct{})
SignalC := make(chan os.Signal)
signal.Notify(SignalC, syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT)
go func() {
for s := range SignalC {
switch s {
case syscall.SIGHUP, syscall.SIGINT, syscall.SIGTERM, syscall.SIGQUIT:
close(exit)
return
}
}
}()
<-exit
socketio.Close(nil)
os.Exit(0)
}WebTransport client (js): const manager = new io.Manager("https://domain", {
transports: ['webtransport'],
});
const socket = manager.socket("/", {
reconnectionDelayMax: 10000,
auth: { token: "123" },
query: {
"my-key": "my-value"
}
});I have tested the above code snippet locally, and it runs correctly on both Firefox and Chrome browsers. Note: You need a CA-trusted certificate rather than a self-signed certificate. |
Beta Was this translation helpful? Give feedback.
-
|
wow awesome @zishang520. I just updated my example app with your suggestion: I need to try this with a CA-trusted cert locally, as I'm getting:
with openssl created cert will report back with my findings |
Beta Was this translation helpful? Give feedback.
-
|
You can obtain a CA-trusted certificate using tools like acme.sh. Then, you can test it by modifying the host's hosts file or using a reverse proxy such as ngrok. |
Beta Was this translation helpful? Give feedback.
other: Use gin(Not necessary) + webtransport