예제 #1
0
파일: websocket.go 프로젝트: luke/subhub
func (h *handler) handleWebsocket(rw http.ResponseWriter, req *http.Request) {
	// conn, err := websocket.Upgrade(rw, req, nil, WebSocketReadBufSize, WebSocketWriteBufSize)

	req.ParseForm()
	sid := req.Form.Get("sid") // , _ := h.parseSessionID(req.URL)
	if sid == "" {
		sid = uuid.NewRandom().String()
	}
	rw.Header().Add("sid", sid)

	conn, err := wsUpgrader.Upgrade(rw, req, nil)
	if _, ok := err.(websocket.HandshakeError); ok {
		http.Error(rw, `Can "Upgrade" only to "WebSocket".`, http.StatusBadRequest)
		return
	} else if err != nil {
		rw.WriteHeader(http.StatusInternalServerError)
		return
	}

	path := req.RequestURI
	sess := newSession(sid, h.options.DisconnectDelay, h.options.HeartbeatDelay, path)
	if h.handlerFunc != nil {
		go h.handlerFunc(sess)
	}

	receiver := newWsReceiver(conn)
	sess.attachReceiver(receiver)
	readCloseCh := make(chan struct{})
	go func() {
		for {

			// todo: refactor needed
			// kind of silly to be doing all this
			// read > accept > encode > decode > yada lark
			// can just do.. c.ws.ReadJSON(&msg)

			t, m, err := conn.ReadMessage()
			if err != nil {
				log.Println("error reading message, calling close", err)
				close(readCloseCh)
				return
			}
			if t != websocket.TextMessage {
				log.Println("only accept text messages, closing")
				close(readCloseCh)
				return
			}
			sess.accept(string(m))
		}
	}()

	select {
	case <-readCloseCh:
	case <-receiver.doneNotify():
	}
	sess.close()
	conn.Close()
}
예제 #2
0
파일: server.go 프로젝트: luke/subhub
func (s *server) newSocket(session Session, path string) *socket {
	log.Println("new socket %s with path: %s", session.ID(), path)
	id := uuid.NewRandom().String()
	sock := &socket{
		id:       id,
		session:  session,
		path:     path,
		presense: make(map[string]string),
		server:   s,
	}
	return sock
}
예제 #3
0
파일: pubsub.go 프로젝트: luke/subhub
func New(opts *Options) PubSub { // todo: this should return PubSub iface
	ps := &pubsub{
		opts:    opts,
		sublist: sublist.New(),
		subs:    make(map[Subscriber]*set.Set),
		topics:  make(map[string]*set.Set),
	}
	// set to random id if not set
	if opts.PubSubNodeId == "" {
		log.Println("pub sub node id not set, setting to uuid")
		// todo: truncate this to say 16 chars?
		opts.PubSubNodeId = uuid.NewRandom().String()
	}
	log.Println("pub sub node id:", opts.PubSubNodeId)
	if opts.PubSubMode != PubSubModeNormal && opts.PubSubMode != PubSubModeFirehose {
		log.Println("pub sub mode not set using normal mode")
		opts.PubSubMode = PubSubModeNormal
	}
	// Ensure interface compliance
	var _ PubSub = ps
	return ps
}
예제 #4
0
파일: app.go 프로젝트: luke/subhub
func newId() string {
	return uuid.NewRandom().String()
}