func (h *streamHandler) onDefault(name string, callback float64, r *amf0.Reader) error { if p := h.publish.p; p == nil { xlog.OutLog.Printf("[session]: xid = %d, reader.fid = %d, writer.fid = %d, message on non-published stream\n", h.session.xid, h.fr.fid, h.fw.fid) return nil } else if p.rpc { xlog.OutLog.Printf("[session]: xid = %d, reader.fid = %d, writer.fid = %d, unhandled call on rpc stream\n", h.session.xid, h.fr.fid, h.fw.fid) return nil } else { if w, err := newAmfBytesWriter(name); err != nil { return errors.New("stream.onAmfData.write name") } else if err := w.WriteBytes(r.Bytes()); err != nil { return errors.New("stream.onAmfData.write body") } else { data := split(w.Bytes()) call := func(x *streamHandler) { s := x.session s.Lock() defer s.Unlock() if s.closed || x.play.p != p { return } defer s.flush() x.fw.AddFragments(p.reliable, data...) } async.Call(p.gid, func() { if l, ok := p.list(); ok && l != nil { for e := l.Front(); e != nil; e = e.Next() { call(e.Value.(*streamHandler)) } } }) } return nil } }
func BroadcastByXid(xids []uint32, data []byte, from uint32, reliable bool) { if bs, err := newBroadcastByXidMessage(data, from, reliable); err != nil { xlog.ErrLog.Printf("[session]: broadcastByXid error = '%v'\n", err) } else { data := split(bs) call := func(s *Session) { s.Lock() defer s.Unlock() if s.closed { return } defer s.flush() if fw := s.mainfw; fw != nil { fw.AddFragments(reliable, data...) } } async.Call(uint64(time.Now().UnixNano()), func() { for _, xid := range xids { if s := FindByXid(xid); s != nil { call(s) } } }) } }
func Exit(xid uint32, raddr *net.UDPAddr) { if clt := tcp.GetClient(); clt == nil { return } else if bs, err := newXRequest(xid, raddr, "exit", 0, nil, true); err != nil { counts.Count("rpc.exit.error", 1) xlog.ErrLog.Printf("[rpc]: rpc exit error = '%v'\n", err) } else { counts.Count("rpc.exit", 1) async.Call(uint64(xid), func() { clt.Send(bs) }) } }
func CloseAll(xids []uint32) { call := func(s *Session) { s.Lock() defer s.Unlock() s.Close() } async.Call(uint64(time.Now().UnixNano()), func() { for _, xid := range xids { if s := FindByXid(xid); s != nil { call(s) } } }) }
func Call(xid uint32, raddr *net.UDPAddr, callback float64, data []byte, reliable bool) { if clt := tcp.GetClient(); clt == nil { counts.Count("rpc.call.noclient", 1) xlog.ErrLog.Printf("[rpc]: rpc is disabled\n") } else if bs, err := newXRequest(xid, raddr, "call", callback, data, reliable); err != nil { counts.Count("rpc.call.error", 1) xlog.ErrLog.Printf("[rpc]: rpc call error = '%v'\n", err) } else { counts.Count("rpc.call", 1) async.Call(uint64(xid), func() { clt.Send(bs) }) } }
func Callback(xid uint32, data []byte, callback float64, reliable bool) { if bs, err := newCallbackMessage(callback, data); err != nil { xlog.ErrLog.Printf("[session]: callback error = '%v'\n", err) } else { async.Call(uint64(time.Now().UnixNano()), func() { if s := FindByXid(xid); s != nil { s.Lock() defer s.Unlock() if s.closed { return } defer s.flush() if fw := s.mainfw; fw != nil { fw.AddFragments(reliable, split(bs)...) } } }) } }
func (h *streamHandler) onPublish(callback float64, r *amf0.Reader) error { if err := h.disenage(); err != nil { return errors.New("stream.onPublish.disenage") } if stream, err := r.ReadString(); err != nil { return errors.New("stream.onPublish.read stream") } else { if p := newPublication(stream); p.start(h) { if err := h.newPublishSuccessResponse(stream, callback); err != nil { return errors.New("stream.onPublish.publish response") } h.publish.p, h.unstable = p, !p.reliable h.publish.callback = callback if !p.rpc { call := func(x *streamHandler) { s := x.session s.Lock() defer s.Unlock() if s.closed || x.play.p != p { return } defer s.flush() x.newPublishNotifyResponse(p.name, x.play.callback) } async.Call(p.gid, func() { if l, _ := p.list(); l != nil { for e := l.Front(); e != nil; e = e.Next() { call(e.Value.(*streamHandler)) } } }) } } else { if err := h.newPublishFailedResponse(stream, callback); err != nil { return errors.New("stream.onPublish.failed response") } } return nil } }
func (h *streamHandler) disenage() error { if p := h.play.p; p != nil { name, callback := p.name, h.play.callback h.play.p = nil p.remove(h) if err := h.newUnplayResponse(name, callback); err != nil { return err } } if p := h.publish.p; p != nil { name, callback := p.name, h.publish.callback h.publish.p, h.unstable = nil, false p.stop() if !p.rpc { call := func(x *streamHandler) { s := x.session s.Lock() defer s.Unlock() if s.closed || x.play.p != p { return } defer s.flush() x.newUnpublishNotifyResponse(p.name, x.play.callback) } async.Call(p.gid, func() { if l, _ := p.list(); l != nil { for e := l.Front(); e != nil; e = e.Next() { call(e.Value.(*streamHandler)) } } }) } if err := h.newUnpublishResponse(name, callback); err != nil { return err } } return nil }
func (h *connHandler) onRelay(callback float64, r *amf0.Reader) error { if pidss, err := r.ReadString(); err != nil { return errors.New("conn.onRelay.read pid") } else if pidbs, err := hex.DecodeString(pidss); err != nil || len(pidbs) != 0x20 { return errors.New("conn.onRelay.decode pid") } else if bs, err := newRelayMessage(h.session.pid, r.Bytes()); err != nil { return errors.New("conn.onRelay.generate response") } else { async.Call(uint64(h.session.xid), func() { if s := FindByPid(string(pidbs)); s != nil { s.Lock() defer s.Unlock() if s.closed { return } defer s.flush() if fw := s.mainfw; fw != nil { fw.AddFragments(true, split(bs)...) } } }) return nil } }