package f5 import ( "q5" "sync/atomic" ) /* http的请求分为两种风格 go style: go风格回调的时候不会join主线程,被回调方需要处理线程同步问题 js style: js风格回调时候会自动join主线程,被回调方无需处理线程同步问题 */ const ( GO_STYLE_REQUEST = 1 JS_STYLE_REQUEST = 2 NORMAL_CHANNEL = 1 QUICK_CHANNEL = 2 ) type HttpCliRequestHandle interface { Cancel() bool } type httpCliRequestHandleImpl struct { state int32 //-1: cancel 0:pending 1:started cancelCount int32 } type HttpCliResponse interface { GetErr() error GetJsonData() map[string]interface{} GetRawData() string IsTimeOut() bool } type httpCliResponse struct { err error data map[string]interface{} rawData string isTimeOut bool } type httpCliMgr struct { } func (this *httpCliRequestHandleImpl) Cancel() bool { ok := atomic.CompareAndSwapInt32(&this.state, 0, -1) || atomic.CompareAndSwapInt32(&this.state, -1, -1) atomic.AddInt32(&this.cancelCount, 1) return ok } func (this *httpCliMgr) init() { _app.RegisterIMMsgHandle( IM_HTTP_CLI_MGR_RESPONSE, func(args q5.Args) { cb := args[0].(func(HttpCliResponse)) rsp := args[1].(*httpCliResponse) cb(rsp) }) } func (this *httpCliMgr) unInit() { } func (this *httpCliMgr) SendGoStyleRequest( url string, params map[string]string, cb func(HttpCliResponse)) HttpCliRequestHandle { return this.internalSendRequest( GO_STYLE_REQUEST, NORMAL_CHANNEL, url, params, cb) } func (this *httpCliMgr) SyncSendGoStyleRequest( url string, params map[string]string, cb func(HttpCliResponse)) { chDone := make(chan bool) this.internalSendRequest( GO_STYLE_REQUEST, NORMAL_CHANNEL, url, params, func(rsp HttpCliResponse) { cb(rsp) chDone <- true }) for { select { case <-chDone: close(chDone) return } } } func (this *httpCliMgr) SendJsStyleRequest( url string, params map[string]string, cb func(HttpCliResponse)) HttpCliRequestHandle { return this.internalSendRequest( JS_STYLE_REQUEST, NORMAL_CHANNEL, url, params, cb) } func (this *httpCliMgr) SendQuickChannelGoStyleRequest( url string, params map[string]string, cb func(HttpCliResponse)) HttpCliRequestHandle { return this.internalSendRequest( GO_STYLE_REQUEST, QUICK_CHANNEL, url, params, cb) } func (this *httpCliMgr) SendQuickChannelJsStyleRequest( url string, params map[string]string, cb func(HttpCliResponse)) HttpCliRequestHandle { return this.internalSendRequest( JS_STYLE_REQUEST, QUICK_CHANNEL, url, params, cb) } func (this *httpCliMgr) internalSendRequest( style int32, channel int32, url string, params map[string]string, cb func(HttpCliResponse)) HttpCliRequestHandle { if !(style == GO_STYLE_REQUEST || style == JS_STYLE_REQUEST) { panic("httpCliMgr sytel error") } if !(channel == NORMAL_CHANNEL || channel == QUICK_CHANNEL) { panic("httpCliMgr channel error") } handle := &httpCliRequestHandleImpl{} doFunc := func() { if atomic.CompareAndSwapInt32(&handle.state, 0, 1) { data, err := q5.HttpGet(url, params) if cb == nil { return } rsp := new(httpCliResponse) rsp.init(data, err) if style == GO_STYLE_REQUEST { cb(rsp) } else { _app.AddIMMsg(IM_HTTP_CLI_MGR_RESPONSE, []interface{}{ cb, rsp, }) } } } go doFunc() return handle } func (this *httpCliResponse) init(data string, err error) { this.err = err this.rawData = data } func (this *httpCliResponse) GetErr() error { return this.err } func (this *httpCliResponse) GetJsonData() map[string]interface{} { return this.data } func (this *httpCliResponse) GetRawData() string { return this.rawData } func (this *httpCliResponse) IsTimeOut() bool { return this.isTimeOut }