func (s *SocketChat) Init() error {
	var err error
	s.hostUrl = "wss://socket-message-10.livehouse.in/socket.io/?EIO=3&transport=websocket"
	u, _ := url.Parse(s.hostUrl)
	s.req, err = http.NewRequest("GET", u.String(), nil)
	if err != nil {
		return err
	}
	c, ncErr := websocket.NewClient(s.req)
	s.c = c
	if ncErr != nil {
		return ncErr
	}
	s.InitReadWriteWorker()
	err = s.Pre()
	if err != nil {
		return err
	}
	return nil
}
Exemple #2
0
func TestConn(t *testing.T) {
	Convey("Create conn", t, func() {
		Convey("without transport", func() {
			server := newFakeServer()
			req, err := http.NewRequest("GET", "/", nil)
			So(err, ShouldBeNil)
			resp := httptest.NewRecorder()
			_, err = newServerConn("id", resp, req, server)
			So(err, ShouldEqual, InvalidError)
		})

		Convey("with invalid transport", func() {
			server := newFakeServer()
			req, err := http.NewRequest("GET", "/?transport=websocket", nil)
			So(err, ShouldBeNil)
			resp := httptest.NewRecorder()
			_, err = newServerConn("id", resp, req, server)
			So(err, ShouldNotBeNil)
		})

		Convey("ok", func() {
			Convey("with polling", func() {
				server := newFakeServer()
				req, err := http.NewRequest("GET", "/?transport=polling", nil)
				So(err, ShouldBeNil)
				resp := httptest.NewRecorder()
				conn, err := newServerConn("id", resp, req, server)
				So(err, ShouldBeNil)
				So(conn.Id(), ShouldEqual, "id")
				So(conn.Request(), ShouldEqual, req)
				conn.Close()
			})

			Convey("with websocket", func() {
				server := newFakeServer()
				h := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
					conn, err := newServerConn("id", w, r, server)
					if err != nil {
						t.Fatal(err)
					}
					defer conn.Close()

					if conn.Id() != "id" {
						t.Fatal(err)
					}
					if conn.Request() != r {
						t.Fatal(err)
					}
				}))
				defer h.Close()

				u, _ := url.Parse(h.URL)
				u.Scheme = "ws"
				req, err := http.NewRequest("GET", u.String()+"/?transport=websocket", nil)
				So(err, ShouldBeNil)
				So(req, ShouldNotBeNil)

				c, err := websocket.NewClient(req)
				So(err, ShouldBeNil)
				defer c.Close()
			})

		})
	})

	Convey("Upgrade conn", t, func() {
		Convey("polling to websocket", func() {
			server := newFakeServer()
			id := "id"
			var conn *serverConn

			h := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
				if conn == nil {
					var err error
					conn, err = newServerConn(id, w, r, server)
					if err != nil {
						t.Fatal(err)
					}
				}

				conn.ServeHTTP(w, r)
			}))
			defer h.Close()

			u, err := url.Parse(h.URL)
			So(err, ShouldBeNil)

			req, err := http.NewRequest("GET", u.String()+"/?transport=polling", nil)
			So(err, ShouldBeNil)
			pc, err := polling.NewClient(req)
			So(err, ShouldBeNil)

			decoder, err := pc.NextReader()
			So(err, ShouldBeNil)
			So(pc.Response().StatusCode, ShouldEqual, http.StatusOK)

			So(conn, ShouldNotBeNil)
			So(conn, ShouldImplement, (*Conn)(nil))

			So(decoder.MessageType(), ShouldEqual, message.MessageText)
			So(decoder.Type(), ShouldEqual, parser.OPEN)

			So(conn.getCurrent(), ShouldNotBeNil)
			So(conn.getUpgrade(), ShouldBeNil)

			u.Scheme = "ws"
			req, err = http.NewRequest("GET", u.String()+"/?transport=websocket", nil)
			So(err, ShouldBeNil)
			wc, err := websocket.NewClient(req)
			So(err, ShouldBeNil)

			So(conn.getCurrent(), ShouldNotBeNil)
			So(conn.getUpgrade(), ShouldNotBeNil)

			encoder, err := wc.NextWriter(message.MessageBinary, parser.PING)
			So(err, ShouldBeNil)
			encoder.Write([]byte("probe"))
			encoder.Close()

			decoder, err = wc.NextReader()
			So(err, ShouldBeNil)
			So(wc.Response().StatusCode, ShouldEqual, http.StatusSwitchingProtocols)

			So(decoder.MessageType(), ShouldEqual, message.MessageText)
			So(decoder.Type(), ShouldEqual, parser.PONG)

			pc.Close()

			encoder, err = wc.NextWriter(message.MessageBinary, parser.UPGRADE)
			So(err, ShouldBeNil)
			encoder.Close()

			decoder, err = wc.NextReader()
			So(err, ShouldBeNil)
			So(pc.Response().StatusCode, ShouldEqual, http.StatusOK)

			So(decoder.MessageType(), ShouldEqual, message.MessageText)
			So(decoder.Type(), ShouldEqual, parser.PING)

			So(conn.getCurrent(), ShouldNotBeNil)
			So(conn.getUpgrade(), ShouldBeNil)

			wc.Close()

			err = conn.Close()
			So(err, ShouldBeNil)

			time.Sleep(time.Second)

			server.closedLocker.Lock()
			So(server.closed[id], ShouldEqual, 1)
			server.closedLocker.Unlock()

			err = conn.Close()
			So(err, ShouldBeNil)

			time.Sleep(time.Second)

			server.closedLocker.Lock()
			So(server.closed[id], ShouldEqual, 1)
			server.closedLocker.Unlock()
		})

		Convey("close when upgrading", func() {
			server := newFakeServer()
			id := "id"
			var conn *serverConn

			h := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
				if conn == nil {
					var err error
					conn, err = newServerConn(id, w, r, server)
					if err != nil {
						t.Fatal(err)
					}
				}

				conn.ServeHTTP(w, r)
			}))
			defer h.Close()

			u, err := url.Parse(h.URL)
			So(err, ShouldBeNil)

			req, err := http.NewRequest("GET", u.String()+"/?transport=polling", nil)
			So(err, ShouldBeNil)
			pc, err := polling.NewClient(req)
			So(err, ShouldBeNil)

			decoder, err := pc.NextReader()
			So(err, ShouldBeNil)
			So(pc.Response().StatusCode, ShouldEqual, http.StatusOK)

			So(conn, ShouldNotBeNil)
			So(conn, ShouldImplement, (*Conn)(nil))

			So(decoder.MessageType(), ShouldEqual, message.MessageText)
			So(decoder.Type(), ShouldEqual, parser.OPEN)

			So(conn.getCurrent(), ShouldNotBeNil)
			So(conn.getUpgrade(), ShouldBeNil)

			u.Scheme = "ws"
			req, err = http.NewRequest("GET", u.String()+"/?transport=websocket", nil)
			So(err, ShouldBeNil)
			wc, err := websocket.NewClient(req)
			So(err, ShouldBeNil)

			So(conn.getCurrent(), ShouldNotBeNil)
			So(conn.getUpgrade(), ShouldNotBeNil)

			encoder, err := wc.NextWriter(message.MessageBinary, parser.PING)
			So(err, ShouldBeNil)
			encoder.Write([]byte("probe"))
			encoder.Close()

			decoder, err = wc.NextReader()
			So(err, ShouldBeNil)
			So(wc.Response().StatusCode, ShouldEqual, http.StatusSwitchingProtocols)

			err = conn.Close()
			So(err, ShouldBeNil)

			wc.Close()
			pc.Close()
			time.Sleep(time.Second)

			server.closedLocker.Lock()
			So(server.closed[id], ShouldEqual, 1)
			server.closedLocker.Unlock()
		})

	})

	Convey("Closing", t, func() {
		Convey("close timeout by polling", func() {
			server := newFakeServer()
			id := "id"
			var conn *serverConn

			h := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
				if conn == nil {
					var err error
					conn, err = newServerConn(id, w, r, server)
					if err != nil {
						t.Fatal(err)
					}
				}

				conn.ServeHTTP(w, r)
			}))
			defer h.Close()

			u, err := url.Parse(h.URL)
			So(err, ShouldBeNil)

			req, err := http.NewRequest("GET", u.String()+"/?transport=polling", nil)
			So(err, ShouldBeNil)
			pc, err := polling.NewClient(req)
			So(err, ShouldBeNil)

			decoder, err := pc.NextReader()
			So(err, ShouldBeNil)

			So(decoder.MessageType(), ShouldEqual, message.MessageText)
			So(decoder.Type(), ShouldEqual, parser.OPEN)

			pc.Close()

			time.Sleep(time.Second * 3)

			server.closedLocker.Lock()
			So(server.closed[id], ShouldEqual, 1)
			server.closedLocker.Unlock()

			err = conn.Close()
			So(err, ShouldBeNil)
		})

		Convey("close by websocket", func() {
			server := newFakeServer()
			id := "id"
			var conn *serverConn
			var locker sync.Mutex

			h := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
				locker.Lock()
				defer locker.Unlock()
				if conn == nil {
					conn, _ = newServerConn(id, w, r, server)
					return
				}

				conn.ServeHTTP(w, r)
			}))
			defer h.Close()

			u, err := url.Parse(h.URL)
			So(err, ShouldBeNil)

			u.Scheme = "ws"
			req, err := http.NewRequest("GET", u.String()+"/?transport=websocket", nil)
			So(err, ShouldBeNil)
			wc, err := websocket.NewClient(req)
			So(err, ShouldBeNil)

			wc.Close()

			time.Sleep(time.Second / 2)

			server.closedLocker.Lock()
			So(server.closed[id], ShouldEqual, 1)
			server.closedLocker.Unlock()

			locker.Lock()
			err = conn.Close()
			locker.Unlock()
			So(err, ShouldBeNil)
		})

	})
}