func goodClient(b binder.Portal, expecting int, t *testing.T, wg *sync.WaitGroup) { changes := b.BaseVersion() + 1 seen := 0 for tform := range b.TransformReadChan() { seen++ if tform.Insert != fmt.Sprintf("%v", changes) { t.Errorf("Wrong order of transforms, expected %v, received %v", changes, tform.Insert) } changes++ } if seen != expecting { t.Errorf("Good client didn't receive all expected transforms: %v != %v", expecting, seen) } wg.Done() }
/* WebsocketHandler - Returns a websocket handler that routes new websockets to a curator. Use this with an HTTP server with the "golang.org/x/net/websocket" package. */ func WebsocketHandler( finder curator.Type, timeout time.Duration, logger log.Modular, stats metrics.Aggregator, ) func(ws *websocket.Conn) { return func(ws *websocket.Conn) { var err error var session binder.Portal defer func() { if err != nil { websocket.JSON.Send(ws, leapHTTPServerMessage{ Type: "error", Error: fmt.Sprintf("socket initialization failed: %v", err), }) } if err = ws.Close(); err != nil { logger.Errorf("Failed to close socket: %v\n", err) } stats.Decr("http.open_websockets", 1) }() stats.Incr("http.websocket.opened", 1) stats.Incr("http.open_websockets", 1) for session == nil && err == nil { var clientMsg leapHTTPClientMessage websocket.JSON.Receive(ws, &clientMsg) switch clientMsg.Command { case "create": if clientMsg.Document == nil { err = ErrInvalidDocument } else { session, err = finder.CreateDocument( clientMsg.UserID, clientMsg.Token, *clientMsg.Document, timeout) } case "read": if len(clientMsg.DocID) <= 0 { err = ErrInvalidDocument } else { session, err = finder.ReadDocument( clientMsg.UserID, clientMsg.Token, clientMsg.DocID, timeout) } case "edit": if len(clientMsg.DocID) <= 0 { err = ErrInvalidDocument } else { session, err = finder.EditDocument( clientMsg.UserID, clientMsg.Token, clientMsg.DocID, timeout) } case "ping": // Ignore and continue waiting for init message. default: err = fmt.Errorf( "first command must be init or ping, client sent: %v", clientMsg.Command, ) } } if session != nil && err == nil { version := session.BaseVersion() websocket.JSON.Send(ws, leapHTTPServerMessage{ Type: "document", Document: session.Document(), Version: &version, }) session.ReleaseDocument() // Begin serving websocket IO. serveWebsocketIO(ws, session, timeout, logger, stats) } } }