mirror of
https://github.com/elobuff/gortmp
synced 2025-12-24 13:08:13 +08:00
Rename result to response, add room for alternate responses
This commit is contained in:
24
client.go
24
client.go
@@ -31,8 +31,8 @@ type Client struct {
|
||||
inChunkSize uint32
|
||||
inChunkStreams map[uint32]*InboundChunkStream
|
||||
|
||||
results map[uint32]*Result
|
||||
resultsMutex sync.Mutex
|
||||
responses map[uint32]*Response
|
||||
responsesMutex sync.Mutex
|
||||
|
||||
lastTransactionId uint32
|
||||
connectionId string
|
||||
@@ -83,7 +83,7 @@ func (c *Client) Reset() {
|
||||
c.inChunkSize = DEFAULT_CHUNK_SIZE
|
||||
c.inWindowSize = DEFAULT_WINDOW_SIZE
|
||||
c.inChunkStreams = make(map[uint32]*InboundChunkStream)
|
||||
c.results = make(map[uint32]*Result)
|
||||
c.responses = make(map[uint32]*Response)
|
||||
c.lastTransactionId = 0
|
||||
c.connectionId = ""
|
||||
}
|
||||
@@ -142,7 +142,7 @@ func (c *Client) NextTransactionId() uint32 {
|
||||
return atomic.AddUint32(&c.lastTransactionId, 1)
|
||||
}
|
||||
|
||||
func (c *Client) Call(msg *Message, t uint32) (result *Result, err error) {
|
||||
func (c *Client) Call(msg *Message, t uint32) (response *Response, err error) {
|
||||
c.outMessages <- msg
|
||||
|
||||
tid := msg.TransactionId
|
||||
@@ -152,19 +152,19 @@ func (c *Client) Call(msg *Message, t uint32) (result *Result, err error) {
|
||||
for {
|
||||
select {
|
||||
case <-poll:
|
||||
c.resultsMutex.Lock()
|
||||
result = c.results[tid]
|
||||
if result != nil {
|
||||
log.Trace("client call: found result for %d", tid)
|
||||
delete(c.results, tid)
|
||||
c.responsesMutex.Lock()
|
||||
response = c.responses[tid]
|
||||
if response != nil {
|
||||
log.Trace("client call: found response for %d", tid)
|
||||
delete(c.responses, tid)
|
||||
}
|
||||
c.resultsMutex.Unlock()
|
||||
c.responsesMutex.Unlock()
|
||||
|
||||
if result != nil {
|
||||
if response != nil {
|
||||
return
|
||||
}
|
||||
case <-timeout:
|
||||
return result, Error("timed out (no response after %d seconds)", t)
|
||||
return response, Error("timed out (no response after %d seconds)", t)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,23 +13,23 @@ func (c *Client) connect() (id string, err error) {
|
||||
return id, Error("client connect: unable to encode connect command: %s", err)
|
||||
}
|
||||
|
||||
var result *Result
|
||||
result, err = c.Call(msg, 10)
|
||||
var response *Response
|
||||
response, err = c.Call(msg, 10)
|
||||
if err != nil {
|
||||
return id, Error("client connect: unable to complete connect: %s", err)
|
||||
}
|
||||
|
||||
if !result.IsResult() {
|
||||
return id, Error("client connect: connect result unsuccessful: %#v", result)
|
||||
if !response.IsResult() {
|
||||
return id, Error("client connect: connect result unsuccessful: %#v", response)
|
||||
}
|
||||
|
||||
obj, ok := result.Objects[1].(amf.Object)
|
||||
obj, ok := response.Objects[1].(amf.Object)
|
||||
if !ok {
|
||||
return id, Error("client connect: unable to find connect response: %#v", result)
|
||||
return id, Error("client connect: unable to find connect response: %#v", response)
|
||||
}
|
||||
|
||||
if obj["code"] != "NetConnection.Connect.Success" {
|
||||
return id, Error("client connect: connection was unsuccessful: %#v", result)
|
||||
return id, Error("client connect: connection was unsuccessful: %#v", response)
|
||||
}
|
||||
|
||||
id = obj["id"].(string)
|
||||
|
||||
@@ -23,15 +23,15 @@ func (c *Client) routeLoop() {
|
||||
}
|
||||
|
||||
func (c *Client) routeCommandMessage(msg *Message) {
|
||||
result, err := msg.DecodeResult(&c.dec)
|
||||
response, err := msg.DecodeResponse(&c.dec)
|
||||
if err != nil {
|
||||
log.Error("unable to decode message type %d on stream %d into command, discarding: %s", msg.Type, msg.ChunkStreamId, err)
|
||||
return
|
||||
}
|
||||
|
||||
tid := uint32(result.TransactionId)
|
||||
tid := uint32(response.TransactionId)
|
||||
|
||||
c.resultsMutex.Lock()
|
||||
c.results[tid] = result
|
||||
c.resultsMutex.Unlock()
|
||||
c.responsesMutex.Lock()
|
||||
c.responses[tid] = response
|
||||
c.responsesMutex.Unlock()
|
||||
}
|
||||
|
||||
26
message.go
26
message.go
@@ -24,46 +24,46 @@ func (m *Message) RemainingBytes() uint32 {
|
||||
return m.Length - uint32(m.Buffer.Len())
|
||||
}
|
||||
|
||||
func (m *Message) DecodeResult(dec *amf.Decoder) (result *Result, err error) {
|
||||
result = new(Result)
|
||||
func (m *Message) DecodeResponse(dec *amf.Decoder) (response *Response, err error) {
|
||||
response = new(Response)
|
||||
|
||||
if m.ChunkStreamId != CHUNK_STREAM_ID_COMMAND {
|
||||
return result, Error("message is not a command message")
|
||||
return response, Error("message is not a command message")
|
||||
}
|
||||
|
||||
switch m.Type {
|
||||
case MESSAGE_TYPE_AMF3:
|
||||
_, err = m.Buffer.ReadByte()
|
||||
if err != nil {
|
||||
return result, Error("unable to read first byte of amf3 message")
|
||||
return response, Error("unable to read first byte of amf3 message")
|
||||
}
|
||||
fallthrough
|
||||
|
||||
case MESSAGE_TYPE_AMF0:
|
||||
result.Name, err = dec.DecodeAmf0String(m.Buffer, true)
|
||||
response.Name, err = dec.DecodeAmf0String(m.Buffer, true)
|
||||
if err != nil {
|
||||
return result, Error("unable to read command from amf message")
|
||||
return response, Error("unable to read command from amf message")
|
||||
}
|
||||
|
||||
result.TransactionId, err = dec.DecodeAmf0Number(m.Buffer, true)
|
||||
response.TransactionId, err = dec.DecodeAmf0Number(m.Buffer, true)
|
||||
if err != nil {
|
||||
return result, Error("unable to read tid from amf message")
|
||||
return response, Error("unable to read tid from amf message")
|
||||
}
|
||||
|
||||
var obj interface{}
|
||||
for m.Buffer.Len() > 0 {
|
||||
obj, err = dec.Decode(m.Buffer, 0)
|
||||
if err != nil {
|
||||
return result, Error("unable to read object from amf message: %s", err)
|
||||
return response, Error("unable to read object from amf message: %s", err)
|
||||
}
|
||||
|
||||
result.Objects = append(result.Objects, obj)
|
||||
response.Objects = append(response.Objects, obj)
|
||||
}
|
||||
default:
|
||||
return result, Error("unable to decode message: %+v", m)
|
||||
return response, Error("unable to decode message: %+v", m)
|
||||
}
|
||||
|
||||
log.Debug("command decoded: %+v", result)
|
||||
log.Debug("command decoded: %+v", response)
|
||||
|
||||
return result, err
|
||||
return response, err
|
||||
}
|
||||
|
||||
@@ -4,34 +4,46 @@ import (
|
||||
"github.com/elobuff/goamf"
|
||||
)
|
||||
|
||||
type Result struct {
|
||||
type Response struct {
|
||||
Name string
|
||||
TransactionId float64
|
||||
Objects []interface{}
|
||||
}
|
||||
|
||||
type ResultError struct {
|
||||
type ResponseError struct {
|
||||
Type string
|
||||
ErrorCode string
|
||||
Message string
|
||||
Substitution string
|
||||
}
|
||||
|
||||
func (r *Result) IsResult() bool {
|
||||
func (r *Response) IsResult() bool {
|
||||
return r.Name == "_result"
|
||||
}
|
||||
|
||||
func (r *Result) IsError() bool {
|
||||
func (r *Response) IsError() bool {
|
||||
return r.Name == "_error"
|
||||
}
|
||||
|
||||
func (r *Result) DecodeError() (result ResultError, err error) {
|
||||
func (r *Response) DecodeBody() (result interface{}, err error) {
|
||||
for _, obj := range r.Objects {
|
||||
if tobj, ok := obj.(amf.TypedObject); ok == true {
|
||||
if body := tobj.Object["body"]; body != nil {
|
||||
return body, nil
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result, Error("Could not extract body")
|
||||
}
|
||||
|
||||
func (r *Response) DecodeError() (result ResponseError, err error) {
|
||||
for _, obj := range r.Objects {
|
||||
if tobj, ok := obj.(amf.TypedObject); ok == true {
|
||||
if tobj.Type == "flex.messaging.messages.ErrorMessage" {
|
||||
if rc := tobj.Object["rootCause"]; rc != nil {
|
||||
if rootCause, ok := rc.(amf.TypedObject); ok == true {
|
||||
result = *new(ResultError)
|
||||
result = *new(ResponseError)
|
||||
result.Type = rootCause.Type
|
||||
|
||||
if tmp, ok := rootCause.Object["errorCode"].(string); ok {
|
||||
Reference in New Issue
Block a user