Skip to content

Instantly share code, notes, and snippets.

@CGamesPlay
Created May 20, 2021 23:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save CGamesPlay/e60cc04d01c2adbec97f7b2cd5622d51 to your computer and use it in GitHub Desktop.
Save CGamesPlay/e60cc04d01c2adbec97f7b2cd5622d51 to your computer and use it in GitHub Desktop.
Capnp-go web sockets server
package main
import (
"fmt"
"io"
"net/http"
"github.com/gin-gonic/gin"
"github.com/gorilla/websocket"
"github.com/spf13/afero"
"zombiezen.com/go/capnproto2/rpc"
)
const basePath = "."
var fs = afero.NewOsFs()
type wsConnection struct {
*websocket.Conn
reader io.Reader
}
func (wsc *wsConnection) Read(buffer []byte) (int, error) {
if wsc.reader == nil {
_, r, err := wsc.Conn.NextReader()
if err != nil {
return 0, err
}
wsc.reader = r
}
n, err := wsc.reader.Read(buffer)
if err == io.EOF {
// Swallow the EOF and switch to the next reader on the next call.
err = nil
wsc.reader = nil
}
return n, err
}
func (wsc *wsConnection) Write(buffer []byte) (int, error) {
w, err := wsc.Conn.NextWriter(websocket.BinaryMessage)
if err != nil {
return 0, err
}
defer w.Close()
return w.Write(buffer)
}
var wsupgrader = websocket.Upgrader{
CheckOrigin: func(r *http.Request) bool {
return true
},
}
func wshandler(w http.ResponseWriter, r *http.Request) {
conn, err := wsupgrader.Upgrade(w, r, nil)
defer conn.Close()
if err != nil {
fmt.Printf("failed to set websocket upgrade: %v\n", err)
return
}
wsc := &wsConnection{Conn: conn}
t := rpc.StreamTransport(wsc)
file, err := fs.Open(basePath)
if err != nil {
fmt.Printf("failed to open basePath: %v\n", err)
return
}
node := &FSNodeImpl{Fs: fs, Handle: file}
srv := FSNode_ServerToClient(node)
rpcConn := rpc.NewConn(t, rpc.MainInterface(srv.Client), rpc.ConnLog(nil))
err = rpcConn.Wait()
if err == nil {
} else if err == rpc.ErrConnClosed {
} else if _, ok := err.(rpc.Abort); ok {
} else {
panic(err)
}
}
func main() {
r := gin.Default()
r.GET("/", func(c *gin.Context) {
c.String(200, "We got Gin")
})
r.GET("/ws", func(c *gin.Context) {
wshandler(c.Writer, c.Request)
})
r.Run()
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment