emiago / sipgo

SIP library for writing fast SIP services in GO
BSD 2-Clause "Simplified" License
512 stars 62 forks source link

sipgo ws integarted in webserver #130

Open wnke opened 2 days ago

wnke commented 2 days ago

Hello!

Is is possible to integrate sipgo ws on a http server? In particular I am using Labstack Echo and trying to understand how to go about having /ws using SIPGO and the rest as a simple webserver.

I am asking because all transports on sipgo start their own listener and that would not fit this presuppose.

package main

import (
    "fmt"

    "github.com/labstack/echo/v4"
    "github.com/labstack/echo/v4/middleware"
    "golang.org/x/net/websocket"
)

func hello(c echo.Context) error {
    websocket.Handler(func(ws *websocket.Conn) {
        defer ws.Close()

                // use sipgo here
        for {
            // Write
            err := websocket.Message.Send(ws, "Hello, Client!")
            if err != nil {
                c.Logger().Error(err)
            }

            // Read
            msg := ""
            err = websocket.Message.Receive(ws, &msg)
            if err != nil {
                c.Logger().Error(err)
            }
            fmt.Printf("%s\n", msg)
        }
    }).ServeHTTP(c.Response(), c.Request())
    return nil
}

func main() {
    e := echo.New()
    e.Use(middleware.Logger())
    e.Use(middleware.Recover())
    e.Static("/", "../public")
    e.GET("/ws", hello)
    e.Logger.Fatal(e.Start(":1323"))
}
emiago commented 1 day ago

not currently, but normally what you want is to have this as separate service behind your ingress. This is how I am doing for webrtc with diago. What is your use case? It is needd to inject this connection on transport layer, which could be missing for listeners.

wnke commented 1 day ago

I was looking into having a single service without the need of a ingress proxy and I also want to share session state between the ws endpoint and remaining http endpoints for authentication and such.

One possibility would be having the transportLayer expose the WS tramport and making InitConnection public, but haven't tried it yet:

func hello(c echo.Context) error {
    websocket.Handler(func(ws *websocket.Conn) {
           defer ws.Close()
               srv.TransportLayer().WS.InitConnection(ws, ....)

    }).ServeHTTP(c.Response(), c.Request())
    return nil
}
emiago commented 1 day ago

yes that could be one of solution. Still I would like to have this on transport layer instead going down to transport it self. Reason is to avoid some breaking changes, and some of things you may need still from layer. So srv.TransportLayer().ServeConnectionWS()

I think this should work

wnke commented 1 day ago

Hello again! Thank you for your response!

emiago commented 21 hours ago

Would that be added to the Transport interface? It will impact other transports as well?

hi @wnke it may not be needed, as you want to go to exact transport.

Following this I would still need to be listening for websockets even if I am passing the connections via ServeConnectionWS?

I see no problem with this?