Skip to content

Commit

Permalink
add client partial implementation
Browse files Browse the repository at this point in the history
  • Loading branch information
hesh915 committed Sep 6, 2015
1 parent 6e36399 commit 80ec64d
Show file tree
Hide file tree
Showing 5 changed files with 605 additions and 0 deletions.
70 changes: 70 additions & 0 deletions caller.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,70 @@
package engine_client

import (
"errors"
"fmt"
"reflect"
)

type caller struct {
Func reflect.Value
Args []reflect.Type
}

func newCaller(f interface{}) (*caller, error) {
fv := reflect.ValueOf(f)
if fv.Kind() != reflect.Func {
return nil, fmt.Errorf("f is not func")
}
ft := fv.Type()
if ft.NumIn() == 0 {
return &caller{
Func: fv,
}, nil
}
args := make([]reflect.Type, ft.NumIn())
for i, n := 0, ft.NumIn(); i < n; i++ {
args[i] = ft.In(i)
}

return &caller{
Func: fv,
Args: args,
}, nil
}

func (c *caller) GetArgs() []interface{} {
ret := make([]interface{}, len(c.Args))
for i, argT := range c.Args {
if argT.Kind() == reflect.Ptr {
argT = argT.Elem()
}
v := reflect.New(argT)
ret[i] = v.Interface()
}
return ret
}

func (c *caller) Call(args []interface{}) []reflect.Value {
var a []reflect.Value
diff := 0

a = make([]reflect.Value, len(args))
for i, arg := range args {
v := reflect.ValueOf(arg)
if c.Args[i].Kind() != reflect.Ptr {
if v.IsValid() {
v = v.Elem()
} else {
v = reflect.Zero(c.Args[i])
}
}
a[i+diff] = v
}

if len(args) != len(c.Args) {
return []reflect.Value{reflect.ValueOf([]interface{}{}), reflect.ValueOf(errors.New("Arguments do not match"))}
}

return c.Func.Call(a)
}
116 changes: 116 additions & 0 deletions client.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
package engine_client

import (
"reflect"
"net/http"
"net/url"
"fmt"
)

var defaultTransport = "websocket"

type Options struct {
Transport string //protocol name string,websocket polling...
Query map[string]string //url的附加的参数

}

type Client struct {
opts *Options

socket *clientConn

events map[string]*caller
acks map[int]*caller
}

func NewClient(uri string, opts *Options) (client *Client, err error) {
exist := false
for _, b := range transports {
if b == opts.Transport {
exist = true
}
}
if !exist{
opts.Transport = defaultTransport
}

request := &http.Request{}
request.URL,err = url.Parse(uri)
if err != nil {
return
}
q:= request.URL.Query()
for k,v := range opts.Query{
q.Set(k,v)
}
request.URL.RawQuery = q.Encode()
fmt.Println(request.URL.String())


socket,err := newClientConn(opts.Transport,request)
if err != nil {
return
}

client = &Client{
opts:opts,
socket:socket,

events:make(map[string]*caller),
acks:make(map[int]*caller),
}
return
}

func (client *Client) On(message string, f interface{}) (err error) {
c, err := newCaller(f)
if err != nil {
return
}
client.events[message] = c
return
}

func (client *Client) Emit(message string, args ...interface{}) (err error) {
var c *caller
if l := len(args); l > 0 {
fv := reflect.ValueOf(args[l-1])
if fv.Kind() == reflect.Func {
var err error
c, err = newCaller(args[l-1])
if err != nil {
return err
}
args = args[:l-1]
}
}
args = append([]interface{}{message}, args...)
if c != nil {
id, err := client.sendId(args)
if err != nil {
return err
}
client.acks[id] = c
return nil
}
return client.send(args)
}

func (client *Client) sendId(args []interface{}) (int, error) {
return 0,nil
}

func (client *Client) send(args []interface{}) error {
return nil
}

func (client *Client) handshake(uri string)(err error){

return
}

func (client *Client) handleMessage(msg []byte)(err error){

return
}
Loading

0 comments on commit 80ec64d

Please sign in to comment.