예제 #1
0
func (c *client) NextReader() (*parser.PacketDecoder, error) {
	var reader io.Reader
	for {
		t, r, err := c.conn.NextReader()
		if err != nil {
			return nil, err
		}
		switch t {
		case websocket.TextMessage:
			fallthrough
		case websocket.BinaryMessage:
			reader = r
			return parser.NewDecoder(reader)
		}
	}
}
예제 #2
0
func (s *Server) serveHTTP(w http.ResponseWriter, r *http.Request) {
	defer s.callback.OnClose(s)

	for {
		t, r, err := s.conn.NextReader()
		if err != nil {
			s.conn.Close()
			return
		}

		switch t {
		case websocket.TextMessage:
			fallthrough
		case websocket.BinaryMessage:
			decoder, err := parser.NewDecoder(r)
			if err != nil {
				return
			}
			s.callback.OnPacket(decoder)
			decoder.Close()
		}
	}
}
예제 #3
0
func TestConnIoutil(t *testing.T) {

	Convey("Reader", t, func() {
		Convey("Normal read", func() {
			r := bytes.NewBufferString("\x34\xe6\xb5\x8b\xe8\xaf\x95")
			decoder, err := parser.NewDecoder(r)
			So(err, ShouldBeNil)

			closeChan := make(chan struct{})
			reader := newConnReader(decoder, closeChan)
			b := make([]byte, 1024)
			n, err := reader.Read(b)
			So(err, ShouldBeNil)
			So(string(b[:n]), ShouldEqual, "测试")
			n, err = reader.Read(b)
			So(err, ShouldEqual, io.EOF)

			Convey("Wait close", func() {
				check := make(chan int)
				go func() {
					err := reader.Close()
					if err != nil {
						t.Fatal(err)
					}
					check <- 1
				}()

				time.Sleep(time.Second / 10) // wait goroutine start
				select {
				case <-check:
					So("should not run here", ShouldEqual, "")
				default:
				}
				<-closeChan
				time.Sleep(time.Second / 10) // wait goroutine end
				select {
				case <-check:
				default:
					So("should not run here", ShouldEqual, "")
				}

				Convey("Close again", func() {
					err := reader.Close()
					So(err, ShouldBeNil)
				})
			})
		})
	})

	Convey("Wrtier", t, func() {

		Convey("Normal write", func() {
			locker := sync.Mutex{}
			w := bytes.NewBuffer(nil)
			locker.Lock()
			writer := newConnWriter(writeCloser{w}, &locker)

			_, err := writer.Write([]byte("abc"))
			So(err, ShouldBeNil)
			So(w.String(), ShouldEqual, "abc")
			writer.Close()
		})

		Convey("Sync", func() {
			locker := sync.Mutex{}
			w1 := bytes.NewBuffer(nil)
			locker.Lock()
			writer1 := newConnWriter(writeCloser{w1}, &locker)
			check := make(chan int)

			go func() {
				w2 := bytes.NewBuffer(nil)
				locker.Lock()
				writer2 := newConnWriter(writeCloser{w2}, &locker)
				defer writer2.Close()
				check <- 1
			}()

			time.Sleep(time.Second / 10)
			select {
			case <-check:
				So("should not run here", ShouldEqual, "")
			default:
			}
			err := writer1.Close()
			So(err, ShouldBeNil)
			time.Sleep(time.Second / 10) // wait goroutine end
			select {
			case <-check:
			default:
				So("should not run here", ShouldEqual, "")
			}

			Convey("Close again", func() {
				err := writer1.Close()
				So(err, ShouldBeNil)
			})
		})

	})

}