func (m *WebSocketHandler) writer() { l.If("wswriter process - %s - starting", m.subscriber.id) defer close(m.send) defer close(m.closeListener) defer m.ws.Close() defer l.If("wswriter process - %s - stopped", m.subscriber.id) for { select { case message := <-m.send: jsonData, _ := json.Marshal(message) l.If("wswriter process - %s - serve json %s", m.subscriber.id, jsonData) err := websocket.Message.Send(m.ws, string(jsonData)) if err != nil { l.Ef("wswriter process - %s - error writing to socket: %s", m.subscriber.id, err.Error()) } case command := <-m.subscriber.feedListener: var response = SubscriberResponse{Status: 1, Commands: command.data} jsonData, _ := json.Marshal(response) l.If("wswriter process - %s - serve data: %s", m.subscriber.id, string(jsonData)) err := websocket.Message.Send(m.ws, string(jsonData)) if err != nil { l.Ef("wswriter process - %s - error writing to socket: %s", m.subscriber.id, err.Error()) } case <-m.closeListener: l.If("wswriter process - %s - received close command", m.subscriber.id) return case <-time.After(30 * time.Second): l.If("wswriter process - %s - alive", m.subscriber.id) } } }
/** * Http request handler */ func (h *Hub) ServeHTTP(w http.ResponseWriter, r *http.Request) { defer func() { if x := recover(); x != nil { l.Ef("request %s caused error from %s {%s}: %v", r.URL.Path, r.RemoteAddr, r.Form.Encode(), x) } }() w.Header().Set("Access-Control-Allow-Origin", "*") parts := strings.Split(r.URL.Path, "/") command := parts[1] r.ParseForm() startTime := time.Now() l.If("http serving request %s from %s {%s}", r.URL.Path, r.RemoteAddr, r.Form.Encode()) mediator := HttpDataMediator{w: w, r: r} h.route(command, &mediator) delay := float64(time.Now().Sub(startTime).Nanoseconds()) / 1000000.0 l.If("http Served request %s from %s {%s} took %f ms", r.URL.Path, r.RemoteAddr, r.Form.Encode(), delay) }
func (m *WebSocketHandler) reader() { l.I("wsreader process - starting") var subscriberId string = "anonymous" for { var message string err := websocket.Message.Receive(m.ws, &message) if err != nil { l.If("wsreader process - %s - error reading from socket: %s", subscriberId, err.Error()) break } l.If("wsreader process - read from socket %s", string(message)) var command = new(WebSocketCommand) err = json.Unmarshal([]byte(message), command) if err != nil { l.Ef("wsreader process - %s - error unmarshal commad %s", subscriberId, err.Error()) break } var mediator = WebSocketDataMediator{send: m.send, command: *command, RequestId: command.RequestId} // special commands - keep alive and subscribe if command.Command == "keepAlive" { var subscriber = m.hub.subscribers[m.subscriber.id] // subscriber not found if subscriber == nil { l.Wf("wsreader process - %s - timed out!", subscriberId) break } else { subscriber.lastRequest = time.Now().Unix() } } else if command.Command == "subscribe" { var channels = strings.Split(mediator.ReadParameter("channels"), ",") var responseListener = make(chan Subscriber) m.hub.subscriberCommandListener <- HubSubscriberRequest{command: Subscribe, channels: channels, responseListener: responseListener} m.subscriber = <-responseListener subscriberId = m.subscriber.id go m.writer() mediator.WriteResponse(map[string]interface{}{"command": "subscribe", "subscriberId": m.subscriber.id}, "json") close(responseListener) } else { m.hub.route(command.Command, &mediator) } } m.closeListener <- true l.If("wsreader process - %s - stopped", subscriberId) m.ws.Close() }
func (h *Hub) createSubscriber(channels []string) Subscriber { l.If("subscriber creating with channels %s", channels) var id, err = newUUID() if err != nil { l.Ef("Error creation new uuid %s", err.Error()) } subscriber := Subscriber{ id: id, commandListener: make(chan SubscriberControlCommand, 10), feedListener: make(chan SubscriberFeedCommand, subscriberQueueSize), channels: make(map[string]*SubscriberChannel), } channels = append(channels, fmt.Sprintf("private_%s", id)) h.addChannelsToSubscriber(channels, &subscriber) subscriber.lastRequest = time.Now().Unix() go subscriber.subscriberCommandProcess(h) h.subscribers[id] = &subscriber l.If("subscriber %s created with channels %s", id, channels) return subscriber }