예제 #1
0
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)
		}
	}

}
예제 #2
0
/**
* 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)
}
예제 #3
0
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()
}
예제 #4
0
파일: hub.go 프로젝트: kennazeng/comet.go
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
}