├── client
├── wxapp
│ ├── app.wxss
│ ├── pages
│ │ ├── index.json
│ │ ├── index.wxss
│ │ ├── index.wxml
│ │ └── index.js
│ ├── app.json
│ ├── .idea
│ │ ├── markdown-navigator
│ │ │ └── profiles_settings.xml
│ │ └── vcs.xml
│ ├── project.config.json
│ ├── stm
│ │ ├── response.js
│ │ ├── contentprotocol.js
│ │ ├── client.es6.js
│ │ ├── defaultcontentprotocol.js
│ │ └── wxwebsocket.js
│ └── app.js
├── java
│ ├── src
│ │ └── stm
│ │ │ ├── .idea
│ │ │ ├── .gitignore
│ │ │ ├── vcs.xml
│ │ │ ├── misc.xml
│ │ │ └── modules.xml
│ │ │ ├── ContentProtocol.java
│ │ │ ├── Response.java
│ │ │ ├── DefaultContentProtocol.java
│ │ │ └── Client.java
│ ├── test
│ │ ├── META-INF
│ │ │ └── MANIFEST.MF
│ │ └── MainThreadLooper.java
│ ├── out
│ │ └── artifacts
│ │ │ └── stm_client
│ │ │ └── stm.client.jar
│ └── .idea
│ │ ├── vcs.xml
│ │ └── codeStyles
│ │ └── Project.xml
├── ios
│ ├── compile
│ │ ├── autogen.sh
│ │ ├── configure.ac
│ │ └── Makefile.am
│ ├── out
│ │ ├── release
│ │ │ └── libstmclient.a
│ │ └── STMClient.h
│ ├── Log.h
│ ├── test-stm
│ │ ├── test-stm
│ │ │ ├── ViewController.h
│ │ │ ├── AppDelegate.h
│ │ │ ├── main.m
│ │ │ ├── Assets.xcassets
│ │ │ │ └── AppIcon.appiconset
│ │ │ │ │ └── Contents.json
│ │ │ ├── Info.plist
│ │ │ ├── Base.lproj
│ │ │ │ ├── LaunchScreen.storyboard
│ │ │ │ └── Main.storyboard
│ │ │ ├── AppDelegate.m
│ │ │ └── ViewController.mm
│ │ ├── test-stmTests
│ │ │ ├── Info.plist
│ │ │ └── test_stmTests.m
│ │ ├── test-stmUITests
│ │ │ ├── Info.plist
│ │ │ └── test_stmUITests.m
│ │ └── test-stm.xcodeproj
│ │ │ └── xcuserdata
│ │ │ └── xpwu.xcuserdatad
│ │ │ └── xcschemes
│ │ │ └── xcschememanagement.plist
│ ├── STMDefaultContentProtocol.h
│ ├── STMResponse.m
│ ├── STMResponse.h
│ ├── STMContentProtocol.h
│ ├── STMNet.h
│ ├── STMClient.h
│ ├── STMDefaultContentProtocol.m
│ ├── ios-sdk
│ │ └── ios-sdk
│ │ │ └── main.m
│ └── STMClient.m
└── js
│ ├── .idea
│ ├── modules.xml
│ └── js.iml
│ ├── stm.response.js
│ ├── gulpfile.js
│ ├── stm.client.extern.js
│ ├── dest
│ ├── stm.client.extern.js
│ ├── stm.client.min.js
│ └── stringview.min.js
│ ├── stm.contentprotocol.js
│ ├── test
│ ├── test.html
│ ├── test.min.html
│ └── test.ssl.html
│ ├── stm.defaultcontentprotocol.js
│ └── stm.client.js
├── stream_module
├── ngx_stream_request_set_module
│ ├── config
│ └── ngx_stream_request_set_module.c
├── ngx_stream_request_cut_frame_module
│ ├── config
│ └── ngx_stream_request_cut_frame_module.c
├── ngx_stream_request_fake_http_module
│ └── config
├── ngx_stream_request_http_proxy_module
│ └── config
├── ngx_stream_request_lencontent_module
│ └── config
├── ngx_stream_request_push_data_module
│ ├── config
│ └── ngx_stream_request_push_data_module.c
├── ngx_stream_request_websocket_module
│ └── config
├── ngx_stream_request_push_close_session_module
│ ├── config
│ └── ngx_stream_request_push_close_session_module.c
├── ngx_stream_request_push_module
│ ├── config
│ └── ngx_stream_request_push_module.h
└── ngx_stream_request_core_module
│ ├── ngx_radix64_tree.h
│ ├── ngx_stream_request_upstream.h
│ ├── config
│ ├── ngx_str_str_rbtree.h
│ ├── ngx_stream_request.c
│ ├── ngx_stream_request_variables.h
│ ├── ngx_radix64_tree.c
│ ├── ngx_str_str_rbtree.c
│ ├── ngx_stream_request_script.h
│ ├── ngx_stream_request.h
│ └── ngx_stream_request_upstream.c
├── push
└── php
│ ├── testDataPusher.php
│ ├── testCloseConnectionPusher.php
│ ├── CloseConnectionPusher.inc
│ ├── DataPusher.inc
│ ├── PushState.inc
│ └── Pusher.inc
├── nginx.conf
└── .gitignore
/client/wxapp/app.wxss:
--------------------------------------------------------------------------------
1 |
--------------------------------------------------------------------------------
/client/wxapp/pages/index.json:
--------------------------------------------------------------------------------
1 | {}
--------------------------------------------------------------------------------
/client/wxapp/pages/index.wxss:
--------------------------------------------------------------------------------
1 | /* /pages/index.wxss */
--------------------------------------------------------------------------------
/client/wxapp/app.json:
--------------------------------------------------------------------------------
1 | {
2 | "pages": [
3 | "pages/index"
4 | ]
5 | }
--------------------------------------------------------------------------------
/client/wxapp/pages/index.wxml:
--------------------------------------------------------------------------------
1 |
2 | /pages/index.wxml
3 |
--------------------------------------------------------------------------------
/client/java/src/stm/.idea/.gitignore:
--------------------------------------------------------------------------------
1 | # Default ignored files
2 | /shelf/
3 | /workspace.xml
4 |
--------------------------------------------------------------------------------
/client/ios/compile/autogen.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | touch NEWS README AUTHORS ChangeLog
4 |
5 | aclocal && autoconf && automake -a
6 |
--------------------------------------------------------------------------------
/client/ios/out/release/libstmclient.a:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xpwu/ngx-stream-request-module/HEAD/client/ios/out/release/libstmclient.a
--------------------------------------------------------------------------------
/client/java/test/META-INF/MANIFEST.MF:
--------------------------------------------------------------------------------
1 | Manifest-Version: 1.0
2 | Main-Class: Main
3 | Class-Path: ../stm_client/stm.client.jar
4 |
5 |
6 |
--------------------------------------------------------------------------------
/client/java/out/artifacts/stm_client/stm.client.jar:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/xpwu/ngx-stream-request-module/HEAD/client/java/out/artifacts/stm_client/stm.client.jar
--------------------------------------------------------------------------------
/client/wxapp/.idea/markdown-navigator/profiles_settings.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
--------------------------------------------------------------------------------
/client/java/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/client/wxapp/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/client/java/src/stm/.idea/vcs.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/client/java/src/stm/.idea/misc.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/client/java/src/stm/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/client/js/.idea/modules.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
--------------------------------------------------------------------------------
/client/ios/Log.h:
--------------------------------------------------------------------------------
1 | //
2 | // Log.h
3 | // ios-sdk
4 | //
5 | // Created by xpwu on 2016/12/2.
6 | // Copyright © 2016年 xpwu.xpwu. All rights reserved.
7 | //
8 |
9 | #ifndef Log_h
10 | #define Log_h
11 |
12 | #ifdef NDEBUG
13 |
14 | #define NSLog(...){}
15 |
16 | #endif
17 |
18 | #endif /* Log_h */
19 |
--------------------------------------------------------------------------------
/stream_module/ngx_stream_request_set_module/config:
--------------------------------------------------------------------------------
1 |
2 |
3 | ngx_addon_name="ngx_stream_request_set_module"
4 |
5 | ngx_module_name=ngx_stream_request_set_module
6 | ngx_module_srcs=$ngx_addon_dir/ngx_stream_request_set_module.c
7 | ngx_module_type=STREAM
8 | ngx_module_incs=$ngx_addon_dir
9 |
10 | . auto/module
11 |
12 |
--------------------------------------------------------------------------------
/stream_module/ngx_stream_request_cut_frame_module/config:
--------------------------------------------------------------------------------
1 |
2 |
3 | ngx_addon_name="ngx_stream_request_cut_frame_module"
4 |
5 | ngx_module_name="ngx_stream_request_cut_frame_module"
6 | ngx_module_srcs="$ngx_addon_dir/ngx_stream_request_cut_frame_module.c"
7 | ngx_module_type=STREAM
8 | ngx_module_incs=$ngx_addon_dir
9 |
10 | . auto/module
11 |
12 |
--------------------------------------------------------------------------------
/stream_module/ngx_stream_request_fake_http_module/config:
--------------------------------------------------------------------------------
1 |
2 |
3 | ngx_addon_name="ngx_stream_request_fake_http_module"
4 |
5 | ngx_module_name="ngx_stream_request_fake_http_module"
6 | ngx_module_srcs="$ngx_addon_dir/ngx_stream_request_fake_http_module.c"
7 | ngx_module_type=STREAM
8 | ngx_module_incs=$ngx_addon_dir
9 |
10 | . auto/module
11 |
12 |
--------------------------------------------------------------------------------
/stream_module/ngx_stream_request_http_proxy_module/config:
--------------------------------------------------------------------------------
1 |
2 |
3 | ngx_addon_name="ngx_stream_request_http_proxy_module"
4 |
5 | ngx_module_name=ngx_stream_request_http_proxy_module
6 | ngx_module_srcs=$ngx_addon_dir/ngx_stream_request_http_proxy_module.c
7 | ngx_module_type=STREAM
8 | ngx_module_incs=$ngx_addon_dir
9 |
10 | . auto/module
11 |
12 |
--------------------------------------------------------------------------------
/stream_module/ngx_stream_request_lencontent_module/config:
--------------------------------------------------------------------------------
1 |
2 |
3 | ngx_addon_name="ngx_stream_request_lencontent_module"
4 |
5 | ngx_module_name=ngx_stream_request_lencontent_module
6 | ngx_module_srcs=$ngx_addon_dir/ngx_stream_request_lencontent_module.c
7 | ngx_module_type=STREAM
8 | ngx_module_incs=$ngx_addon_dir
9 |
10 | . auto/module
11 |
12 |
--------------------------------------------------------------------------------
/stream_module/ngx_stream_request_push_data_module/config:
--------------------------------------------------------------------------------
1 |
2 |
3 | ngx_addon_name="ngx_stream_request_push_data_module"
4 |
5 | ngx_module_name="ngx_stream_request_push_data_module"
6 | ngx_module_srcs="$ngx_addon_dir/ngx_stream_request_push_data_module.c"
7 | ngx_module_type=STREAM
8 | ngx_module_incs=$ngx_addon_dir
9 |
10 | . auto/module
11 |
12 |
--------------------------------------------------------------------------------
/stream_module/ngx_stream_request_websocket_module/config:
--------------------------------------------------------------------------------
1 |
2 |
3 | ngx_addon_name="ngx_stream_request_websocket_module"
4 |
5 | ngx_module_name=ngx_stream_request_websocket_module
6 | ngx_module_srcs=$ngx_addon_dir/ngx_stream_request_websocket_module.c
7 | ngx_module_type=STREAM
8 | ngx_module_incs=$ngx_addon_dir
9 |
10 | . auto/module
11 |
12 |
--------------------------------------------------------------------------------
/client/ios/test-stm/test-stm/ViewController.h:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.h
3 | // test-stm
4 | //
5 | // Created by xpwu on 2016/12/13.
6 | // Copyright © 2016年 xpwuxpwu. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface ViewController : UIViewController
12 |
13 | -(IBAction)selector:(id)sender;
14 |
15 | @end
16 |
17 |
--------------------------------------------------------------------------------
/client/ios/STMDefaultContentProtocol.h:
--------------------------------------------------------------------------------
1 | //
2 | // STMDefaultContentProtocol.h
3 | // ios-sdk
4 | //
5 | // Created by xpwu on 2016/11/24.
6 | // Copyright © 2016年 xpwu.xpwu. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "STMContentProtocol.h"
11 |
12 | @interface STMDefaultContentProtocol : NSObject
13 |
14 | @end
15 |
--------------------------------------------------------------------------------
/client/ios/test-stm/test-stm/AppDelegate.h:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.h
3 | // test-stm
4 | //
5 | // Created by xpwu on 2016/12/13.
6 | // Copyright © 2016年 xpwuxpwu. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface AppDelegate : UIResponder
12 |
13 | @property (strong, nonatomic) UIWindow *window;
14 |
15 |
16 | @end
17 |
18 |
--------------------------------------------------------------------------------
/client/java/src/stm/ContentProtocol.java:
--------------------------------------------------------------------------------
1 | package stm;
2 |
3 | /**
4 | *
5 | * Created by xpwu on 2016/11/29.
6 | */
7 |
8 | import java.util.Map;
9 |
10 | interface ContentProtocol {
11 | public Response parse(byte[] content);
12 | public byte[] build(byte[] body, Mapheaders, long reqID);
13 | public byte[] buildFailedMessage(String error, long reqID);
14 | }
15 |
--------------------------------------------------------------------------------
/stream_module/ngx_stream_request_push_close_session_module/config:
--------------------------------------------------------------------------------
1 |
2 |
3 | ngx_addon_name="ngx_stream_request_push_close_session_module"
4 |
5 | ngx_module_name="ngx_stream_request_push_close_session_module"
6 | ngx_module_srcs="$ngx_addon_dir/ngx_stream_request_push_close_session_module.c"
7 | ngx_module_type=STREAM
8 | ngx_module_incs=$ngx_addon_dir
9 |
10 | . auto/module
11 |
12 |
--------------------------------------------------------------------------------
/stream_module/ngx_stream_request_push_module/config:
--------------------------------------------------------------------------------
1 |
2 |
3 | ngx_addon_name="ngx_stream_request_push_module"
4 |
5 | ngx_module_name="ngx_stream_request_push_module"
6 | ngx_module_srcs="$ngx_addon_dir/ngx_stream_request_push_module.c"
7 | ngx_module_deps="$ngx_addon_dir/ngx_stream_request_push_module.h"
8 | ngx_module_type=STREAM
9 | ngx_module_incs=$ngx_addon_dir
10 |
11 | . auto/module
12 |
13 |
--------------------------------------------------------------------------------
/push/php/testDataPusher.php:
--------------------------------------------------------------------------------
1 | pushTo($argv[1]));
15 | echo "\n";
16 |
17 |
--------------------------------------------------------------------------------
/client/ios/test-stm/test-stm/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // test-stm
4 | //
5 | // Created by xpwu on 2016/12/13.
6 | // Copyright © 2016年 xpwuxpwu. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "AppDelegate.h"
11 |
12 | int main(int argc, char * argv[]) {
13 | @autoreleasepool {
14 | return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
15 | }
16 | }
17 |
--------------------------------------------------------------------------------
/push/php/testCloseConnectionPusher.php:
--------------------------------------------------------------------------------
1 | pushTo($argv[1]));
17 | echo "\n";
18 |
--------------------------------------------------------------------------------
/push/php/CloseConnectionPusher.inc:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/push/php/DataPusher.inc:
--------------------------------------------------------------------------------
1 | data_ = $data;
16 | }
17 |
18 | protected function subProtocolData(): string {
19 | // TODO: Implement subProtocolData() method.
20 | return $this->data_;
21 | }
22 |
23 | private $data_;
24 | }
--------------------------------------------------------------------------------
/client/ios/STMResponse.h:
--------------------------------------------------------------------------------
1 | //
2 | // STMResponse.h
3 | // ios-sdk
4 | //
5 | // Created by xpwu on 2016/11/24.
6 | // Copyright © 2016年 xpwu.xpwu. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | typedef enum {
12 | STMResponseStatusSuccess = 0,
13 | STMResponseStatusFailed = 1
14 | } STMResponseStatus;
15 |
16 | @interface STMResponse : NSObject
17 | @property(nonatomic) uint32_t reqID;
18 | @property(nonatomic) STMResponseStatus status;
19 | @property(nonatomic) NSData* data;
20 |
21 | +(instancetype)defaultResponse;
22 | @end
23 |
--------------------------------------------------------------------------------
/client/wxapp/project.config.json:
--------------------------------------------------------------------------------
1 | {
2 | "description": "项目配置文件。",
3 | "setting": {
4 | "urlCheck": false,
5 | "es6": true,
6 | "postcss": true,
7 | "minified": true,
8 | "newFeature": true
9 | },
10 | "compileType": "miniprogram",
11 | "libVersion": "1.7.0",
12 | "appid": "wx7b2a9c041288294f",
13 | "projectname": "stm-test",
14 | "condition": {
15 | "search": {
16 | "current": -1,
17 | "list": []
18 | },
19 | "conversation": {
20 | "current": -1,
21 | "list": []
22 | },
23 | "miniprogram": {
24 | "current": -1,
25 | "list": []
26 | }
27 | }
28 | }
--------------------------------------------------------------------------------
/client/js/stm.response.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by xpwu on 2016/12/1.
3 | */
4 |
5 |
6 | (function (ns) {
7 | "use strict";
8 |
9 | var stm = ns.stm = ns.stm || {};
10 |
11 | var state = {Success: 0, Failed: 1};
12 |
13 | function Response() {
14 | /**
15 | *
16 | * @type {number}
17 | */
18 | this.reqID = 0;
19 | /**
20 | *
21 | * @type {number}
22 | */
23 | this.state = state.Success;
24 | /**
25 | *
26 | * @type {ArrayBuffer}
27 | */
28 | this.data = null;
29 | }
30 |
31 | stm.Response = Response;
32 | stm.Response.State = state;
33 |
34 | })(this);
--------------------------------------------------------------------------------
/client/java/src/stm/Response.java:
--------------------------------------------------------------------------------
1 | package stm;
2 |
3 | import org.omg.CORBA.PUBLIC_MEMBER;
4 |
5 | /**
6 | *
7 | * Created by xpwu on 2016/11/29.
8 | */
9 | class Response {
10 | enum Status {
11 | Success(0), Failed(1);
12 |
13 | private int code_ = 0;
14 | private Status(int code) {
15 | this.code_ = code;
16 | }
17 | }
18 |
19 | long reqID;
20 | byte[] data;
21 | Status status;
22 |
23 | static public Response defaultResponse(){
24 | Response res = new Response();
25 | res.reqID = 0;
26 | res.status = Status.Success;
27 | res.data = null;
28 |
29 | return res;
30 | }
31 | }
32 |
--------------------------------------------------------------------------------
/client/ios/STMContentProtocol.h:
--------------------------------------------------------------------------------
1 | //
2 | // STMContentProtocol.h
3 | // ios-sdk
4 | //
5 | // Created by xpwu on 2016/11/24.
6 | // Copyright © 2016年 xpwu.xpwu. All rights reserved.
7 | //
8 |
9 | #import
10 | #import "STMResponse.h"
11 |
12 | @protocol STMContentProtocol
13 |
14 | -(void)onopen:(void (^)(void))callback;
15 | -(void)onclose;
16 | -(STMResponse*)parse:(NSData*)message;
17 | -(NSData*)build:(NSData*)body
18 | withHeaders:(NSDictionary*)headers
19 | withReqID:(uint32_t)reqID;
20 |
21 | -(NSData*)buildFailedMessage:(NSString*)error withReqid:(uint32_t)reqID;
22 |
23 | @end
24 |
--------------------------------------------------------------------------------
/client/wxapp/stm/response.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by xpwu on 2016/12/1.
3 | */
4 |
5 |
6 | // (function (ns) {
7 | // "use strict";
8 |
9 | // var stm = ns.stm = ns.stm || {};
10 |
11 | var state = {Success: 0, Failed: 1};
12 |
13 | function Response() {
14 | /**
15 | *
16 | * @type {number}
17 | */
18 | this.reqID = 0;
19 | /**
20 | *
21 | * @type {number}
22 | */
23 | this.state = state.Success;
24 | /**
25 | *
26 | * @type {ArrayBuffer}
27 | */
28 | this.data = null;
29 | }
30 |
31 | // stm.Response = Response;
32 | // stm.Response.State = state;
33 |
34 | module.exports.Response = Response;
35 | module.exports.Response.State = state;
36 |
37 | // })(this);
--------------------------------------------------------------------------------
/stream_module/ngx_stream_request_core_module/ngx_radix64_tree.h:
--------------------------------------------------------------------------------
1 | //
2 | // ngx_radix64_tree.h
3 | // nginx-1.12
4 | //
5 | // Created by xpwu on 2017/12/24.
6 | // Copyright © 2017年 xpwu. All rights reserved.
7 | //
8 |
9 | #ifndef ngx_radix64_tree_h
10 | #define ngx_radix64_tree_h
11 |
12 | #include
13 | #include
14 |
15 | ngx_int_t ngx_radix64tree_insert(ngx_radix_tree_t *tree,
16 | uint64_t key, uint64_t mask, uintptr_t value);
17 | ngx_int_t ngx_radix64tree_delete(ngx_radix_tree_t *tree,
18 | uint64_t key, uint64_t mask);
19 | uintptr_t ngx_radix64tree_find(ngx_radix_tree_t *tree, uint64_t key);
20 |
21 |
22 | #endif /* ngx_radix64_tree_h */
23 |
--------------------------------------------------------------------------------
/stream_module/ngx_stream_request_core_module/ngx_stream_request_upstream.h:
--------------------------------------------------------------------------------
1 | //
2 | // ngx_stream_request_upstream.h
3 | // nginx-1.12
4 | //
5 | // Created by xpwu on 2017/12/16.
6 | // Copyright © 2017年 xpwu. All rights reserved.
7 | //
8 |
9 | #ifndef ngx_stream_request_upstream_h
10 | #define ngx_stream_request_upstream_h
11 |
12 | #include
13 | #include
14 | #include
15 |
16 | struct ngx_stream_request_upstream_s{
17 | ngx_stream_upstream_t upstream;
18 | void (*upstream_connected)(ngx_stream_request_t*);
19 | void (*upstream_connect_failed)(ngx_stream_request_t*, char* reason);
20 | } ;
21 |
22 | extern void ngx_stream_request_upstream_connect(ngx_stream_request_t *r);
23 |
24 |
25 | #endif /* ngx_stream_request_upstream_h */
26 |
--------------------------------------------------------------------------------
/client/ios/compile/configure.ac:
--------------------------------------------------------------------------------
1 | # -*- Autoconf -*-
2 | # Process this file with autoconf to produce a configure script.
3 |
4 | AC_PREREQ([2.69])
5 | AC_INIT([stmclient], [VERSION], [BUG-REPORT-ADDRESS])
6 | AM_INIT_AUTOMAKE
7 | # AC_CONFIG_SRCDIR([STMClient.h])
8 | # AC_CONFIG_HEADERS([config.h])
9 |
10 | AM_CONDITIONAL([MACOS], [test "x$(uname -s)" = "xDarwin"])
11 |
12 | # Checks for programs.
13 | AC_PROG_CXX
14 | AC_PROG_CC
15 | AC_PROG_CPP
16 | AC_PROG_RANLIB
17 | AC_PROG_OBJCXX
18 | AM_PROG_CC_C_O
19 | AC_PROG_OBJC
20 | # Checks for libraries.
21 |
22 | # Checks for header files.
23 |
24 | # Checks for typedefs, structures, and compiler characteristics.
25 | AC_TYPE_UINT16_T
26 | AC_TYPE_UINT32_T
27 | AC_TYPE_UINT8_T
28 |
29 | # Checks for library functions.
30 |
31 | AC_OUTPUT([Makefile])
32 |
--------------------------------------------------------------------------------
/client/ios/test-stm/test-stmTests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/client/ios/test-stm/test-stmUITests/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | BNDL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 |
24 |
25 |
--------------------------------------------------------------------------------
/client/wxapp/app.js:
--------------------------------------------------------------------------------
1 |
2 | let stm = require("stm/client.js");
3 | let es6Client = require("stm/client.es6").Client;
4 |
5 | App({
6 | onLaunch: function() {
7 | this.client = new stm.Client();
8 | this.client.setConnectArgs("ws://127.0.0.1:8001", function(){
9 | console.log("connect success");
10 | }
11 | , function(str){
12 | console.error(str);
13 | });
14 | this.client.onPush = function(data) {
15 | console.log(new stm.Client.StringView(data).toString());
16 | };
17 |
18 | this.es6Client = new es6Client();
19 | this.es6Client.setConnectArgs("ws://127.0.0.1:8001")
20 | .then(()=>console.log("es6 connect success"))
21 | .catch((error)=>{
22 | console.error(error);
23 | })
24 | },
25 |
26 | /**
27 | * @type stm.Client
28 | */
29 | client: null,
30 |
31 | es6Client: null
32 |
33 | })
--------------------------------------------------------------------------------
/client/ios/test-stm/test-stm.xcodeproj/xcuserdata/xpwu.xcuserdatad/xcschemes/xcschememanagement.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | SchemeUserState
6 |
7 | test-stm.xcscheme
8 |
9 | orderHint
10 | 0
11 |
12 |
13 | SuppressBuildableAutocreation
14 |
15 | A425F1251DFFAA7000854907
16 |
17 | primary
18 |
19 |
20 | A425F13E1DFFAA7000854907
21 |
22 | primary
23 |
24 |
25 | A425F1491DFFAA7000854907
26 |
27 | primary
28 |
29 |
30 |
31 |
32 |
33 |
--------------------------------------------------------------------------------
/client/ios/STMNet.h:
--------------------------------------------------------------------------------
1 | //
2 | // STMNet.h
3 | // ios-sdk
4 | //
5 | // Created by xpwu on 2016/11/23.
6 | // Copyright © 2016年 xpwu.xpwu. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | typedef enum{
12 | STMNetStatusConnecting,
13 | STMNetStatusOpen,
14 | STMNetStatusClosed
15 |
16 | } STMNetStatus;
17 |
18 | @interface STMNet : NSObject
19 |
20 | @property(nonatomic) void (^onopen)();
21 | @property(nonatomic) void (^onclose)(NSString*);
22 | @property(nonatomic) void (^onmessage)(NSData*);
23 | @property(nonatomic,readonly) STMNetStatus status;
24 |
25 | // unit: s
26 | @property(nonatomic) NSTimeInterval hearbeatTime;
27 | @property(nonatomic) NSTimeInterval transmissionTimeout;
28 | @property(nonatomic) NSTimeInterval openTimeout;
29 |
30 | -(instancetype)initWithHost:(NSString*)host andPort:(UInt16)port;
31 |
32 | -(void)open;
33 | -(void)close;
34 | -(void)send:(NSData*)data;
35 |
36 | @end
37 |
--------------------------------------------------------------------------------
/push/php/PushState.inc:
--------------------------------------------------------------------------------
1 |
10 |
11 | @interface test_stmTests : XCTestCase
12 |
13 | @end
14 |
15 | @implementation test_stmTests
16 |
17 | - (void)setUp {
18 | [super setUp];
19 | // Put setup code here. This method is called before the invocation of each test method in the class.
20 | }
21 |
22 | - (void)tearDown {
23 | // Put teardown code here. This method is called after the invocation of each test method in the class.
24 | [super tearDown];
25 | }
26 |
27 | - (void)testExample {
28 | // This is an example of a functional test case.
29 | // Use XCTAssert and related functions to verify your tests produce the correct results.
30 | }
31 |
32 | - (void)testPerformanceExample {
33 | // This is an example of a performance test case.
34 | [self measureBlock:^{
35 | // Put the code you want to measure the time of here.
36 | }];
37 | }
38 |
39 | @end
40 |
--------------------------------------------------------------------------------
/client/java/test/MainThreadLooper.java:
--------------------------------------------------------------------------------
1 | import java.util.ArrayList;
2 | import java.util.LinkedList;
3 | import java.util.List;
4 |
5 | /**
6 | *
7 | * Created by xpwu on 2016/11/30.
8 | */
9 |
10 | public class MainThreadLooper {
11 | static interface Handler {
12 | public void run();
13 | }
14 |
15 | static private final List queue = new LinkedList<>();
16 |
17 | static void addHandler(Handler handler) {
18 | synchronized (queue) {
19 | queue.add(handler);
20 | queue.notify();
21 | }
22 | }
23 |
24 | static void loop() {
25 | while (true) {
26 | synchronized (queue) {
27 | while (queue.isEmpty()) {
28 | try {
29 | queue.wait();
30 | } catch (InterruptedException e) {}
31 | }
32 | ArrayList handlers = new ArrayList<>(queue.size());
33 | handlers.addAll(queue);
34 | for (Handler task: handlers) {
35 | task.run();
36 | queue.remove(task);
37 | }
38 | // task.run() 执行过程中, 可能会产生新的task
39 | // queue.clear();
40 | }
41 | }
42 | }
43 | }
44 |
--------------------------------------------------------------------------------
/stream_module/ngx_stream_request_push_module/ngx_stream_request_push_module.h:
--------------------------------------------------------------------------------
1 | //
2 | // ngx_stream_request_push_module.h
3 | // nginx-1.12
4 | //
5 | // Created by xpwu on 2017/12/23.
6 | // Copyright © 2017年 xpwu. All rights reserved.
7 | //
8 |
9 | #ifndef ngx_stream_request_push_module_h
10 | #define ngx_stream_request_push_module_h
11 |
12 | #include
13 | #include
14 | #include
15 |
16 |
17 | // 通过r->data的buffer位置与 ctx->msg的buffer位置 自动判断是否需要重新分配空间
18 | // 具体见 need_copy_data 的实现
19 |
20 | // NGX_OK; NGX_ERROR; NGX_AGAIN;
21 | // 如果返回NGX_AGAIN,在后续流程中需要调用
22 | // ngx_stream_request_push_back_src_process 把request返回原进程
23 | // 执行结束后,必须保证r仍然有效,否则会crash。r中的data就是执行后返回的数据
24 | typedef ngx_int_t
25 | (*ngx_stream_request_push_dist_hander)(ngx_stream_request_t*);
26 |
27 | // NGX_OK; NGX_ERROR; NGX_AGAIN
28 | extern ngx_int_t
29 | ngx_stream_request_push_to_dist_process(ngx_stream_request_t*,
30 | ngx_stream_request_push_dist_hander);
31 |
32 | extern void
33 | ngx_stream_request_push_back_src_process(ngx_stream_request_t*);
34 |
35 |
36 | #endif /* ngx_stream_request_push_module_h */
37 |
--------------------------------------------------------------------------------
/stream_module/ngx_stream_request_core_module/ngx_str_str_rbtree.h:
--------------------------------------------------------------------------------
1 | //
2 | // ngx_str_str_rbtree.h
3 | // ngx-1.10.1-xcode
4 | //
5 | // Created by xpwu on 2016/11/18.
6 | // Copyright © 2016年 xpwu. All rights reserved.
7 | //
8 |
9 | #ifndef ngx_str_str_rbtree_h
10 | #define ngx_str_str_rbtree_h
11 |
12 | #include
13 | #include
14 |
15 | typedef struct{
16 | ngx_rbtree_t tree;
17 | ngx_rbtree_node_t sentinel;
18 | ngx_pool_t* pool;
19 | ngx_log_t* log;
20 | } ngx_str_str_rbtree;
21 |
22 | extern void ngx_str_str_rbtree_init(ngx_str_str_rbtree* tree
23 | , ngx_pool_t* pool, ngx_log_t* log);
24 |
25 | extern ngx_str_t ngx_str_str_rbtree_get_value(ngx_str_str_rbtree* tree
26 | , ngx_str_t key);
27 | extern void ngx_str_str_rbtree_set_value(ngx_str_str_rbtree* tree
28 | , ngx_str_t key
29 | , ngx_str_t value
30 | , ngx_int_t force_rewrite);
31 |
32 | #define ngx_str_str_rbtree_is_empty(rbtree_ptr) \
33 | ((tree_ptr)->tree->root == (tree_ptr)->tree->sentinel ? 1 : 0);
34 |
35 | #endif /* ngx_str_str_rbtree_h */
36 |
--------------------------------------------------------------------------------
/client/ios/test-stm/test-stmUITests/test_stmUITests.m:
--------------------------------------------------------------------------------
1 | //
2 | // test_stmUITests.m
3 | // test-stmUITests
4 | //
5 | // Created by xpwu on 2016/12/13.
6 | // Copyright © 2016年 xpwuxpwu. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface test_stmUITests : XCTestCase
12 |
13 | @end
14 |
15 | @implementation test_stmUITests
16 |
17 | - (void)setUp {
18 | [super setUp];
19 |
20 | // Put setup code here. This method is called before the invocation of each test method in the class.
21 |
22 | // In UI tests it is usually best to stop immediately when a failure occurs.
23 | self.continueAfterFailure = NO;
24 | // UI tests must launch the application that they test. Doing this in setup will make sure it happens for each test method.
25 | [[[XCUIApplication alloc] init] launch];
26 |
27 | // In UI tests it’s important to set the initial state - such as interface orientation - required for your tests before they run. The setUp method is a good place to do this.
28 | }
29 |
30 | - (void)tearDown {
31 | // Put teardown code here. This method is called after the invocation of each test method in the class.
32 | [super tearDown];
33 | }
34 |
35 | - (void)testExample {
36 | // Use recording to get started writing UI tests.
37 | // Use XCTAssert and related functions to verify your tests produce the correct results.
38 | }
39 |
40 | @end
41 |
--------------------------------------------------------------------------------
/client/wxapp/pages/index.js:
--------------------------------------------------------------------------------
1 |
2 | let stm = require("../stm/client.js");
3 |
4 |
5 | // /pages/index.js
6 | Page({
7 | data:{},
8 | onLoad:function(options){
9 | // 页面初始化 options为页面跳转所带来的参数
10 | },
11 | onReady:function(){
12 | // 页面渲染完成
13 | getApp().client.addRequest("test", function (data) {
14 | console.log(new stm.Client.StringView(data).toString());
15 | }, {api:'/API/GetInfo'}, function (res) {
16 | console.error(res);
17 | }, function () {
18 | console.log("complete");
19 | });
20 |
21 | getApp().es6Client.addJsonRequest("test", {api:'/API/GetInfo'})
22 | .then((res)=>{
23 | console.log(res);
24 | }).catch((error)=>{
25 | console.error(error);
26 | });
27 | },
28 | onShow:function(){
29 | // 页面显示
30 | getApp().client.addRequest("test", function (data) {
31 | console.log(new stm.Client.StringView(data).toString());
32 | }, { api:'/API/GetInfo'}, function (res) {
33 | console.error(res);
34 | }, function () {
35 | console.log("complete");
36 | });
37 |
38 | getApp().es6Client.addJsonRequest("test", {api:'/API/GetInfo'})
39 | .then((res)=>{
40 | console.log(res);
41 | }).catch((error)=>{
42 | console.error(error);
43 | });
44 | },
45 | onHide:function(){
46 | // 页面隐藏
47 | },
48 | onUnload:function(){
49 | // 页面关闭
50 | }
51 | })
52 |
53 |
--------------------------------------------------------------------------------
/client/ios/test-stm/test-stm/Assets.xcassets/AppIcon.appiconset/Contents.json:
--------------------------------------------------------------------------------
1 | {
2 | "images" : [
3 | {
4 | "idiom" : "iphone",
5 | "size" : "29x29",
6 | "scale" : "2x"
7 | },
8 | {
9 | "idiom" : "iphone",
10 | "size" : "29x29",
11 | "scale" : "3x"
12 | },
13 | {
14 | "idiom" : "iphone",
15 | "size" : "40x40",
16 | "scale" : "2x"
17 | },
18 | {
19 | "idiom" : "iphone",
20 | "size" : "40x40",
21 | "scale" : "3x"
22 | },
23 | {
24 | "idiom" : "iphone",
25 | "size" : "60x60",
26 | "scale" : "2x"
27 | },
28 | {
29 | "idiom" : "iphone",
30 | "size" : "60x60",
31 | "scale" : "3x"
32 | },
33 | {
34 | "idiom" : "ipad",
35 | "size" : "29x29",
36 | "scale" : "1x"
37 | },
38 | {
39 | "idiom" : "ipad",
40 | "size" : "29x29",
41 | "scale" : "2x"
42 | },
43 | {
44 | "idiom" : "ipad",
45 | "size" : "40x40",
46 | "scale" : "1x"
47 | },
48 | {
49 | "idiom" : "ipad",
50 | "size" : "40x40",
51 | "scale" : "2x"
52 | },
53 | {
54 | "idiom" : "ipad",
55 | "size" : "76x76",
56 | "scale" : "1x"
57 | },
58 | {
59 | "idiom" : "ipad",
60 | "size" : "76x76",
61 | "scale" : "2x"
62 | }
63 | ],
64 | "info" : {
65 | "version" : 1,
66 | "author" : "xcode"
67 | }
68 | }
--------------------------------------------------------------------------------
/client/js/stm.client.extern.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by xpwu on 2016/11/22.
3 | */
4 |
5 | /*
6 | this file only for IDE
7 | */
8 |
9 | console.error("this file only for IDE");
10 |
11 | stm = stm || {};
12 |
13 | stm.Client = function () {
14 | /**
15 | * @callback pushCallback
16 | * @param {ArrayBuffer}
17 | */
18 |
19 | /**
20 | *
21 | * @type pushCallback
22 | */
23 | this.onPush = 0;
24 |
25 | /**
26 | *
27 | * @var {function(Object)}
28 | */
29 | this.onPushJson = null;
30 | };
31 |
32 | /**
33 | *
34 | * @param {number} connectTimeout unit: s
35 | */
36 | stm.Client.prototype.setConfig = function (connectTimeout){};
37 |
38 | /**
39 | *
40 | * @param {string}url, ws(s)://xxx.xxx.xx:xxx/xxxx
41 | * @param {function()|null} [onSuccess]
42 | * @param {function(string)|null} [onFailed]
43 | */
44 | stm.Client.prototype.setConnectArgs = function(url, onSuccess, onFailed){};
45 |
46 | /**
47 | *
48 | * @param {Object|null} [body]
49 | * @param {function(Object)|null} [onSuccess]
50 | * @param {Object|null} [headers]
51 | * @param {function(string)|null} [onFailed]
52 | * @param {function()|null} [onComplete]
53 | */
54 | stm.Client.prototype.addJsonRequest = function (body, onSuccess, headers, onFailed, onComplete) {};
55 |
56 | /**
57 | *
58 | * @param {ArrayBuffer|string|null} [body]
59 | * @param {function(ArrayBuffer)|null} [onSuccess]
60 | * @param {Object|null} [headers]
61 | * @param {function(string)|null} [onFailed]
62 | * @param {function()|null} [onComplete]
63 | */
64 | stm.Client.prototype.addRequest = function (body, onSuccess, headers, onFailed, onComplete) {};
65 |
--------------------------------------------------------------------------------
/client/js/dest/stm.client.extern.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by xpwu on 2016/11/22.
3 | */
4 |
5 | /*
6 | this file only for IDE
7 | */
8 |
9 | console.error("this file only for IDE");
10 |
11 | stm = stm || {};
12 |
13 | stm.Client = function () {
14 | /**
15 | * @callback pushCallback
16 | * @param {ArrayBuffer}
17 | */
18 |
19 | /**
20 | *
21 | * @type pushCallback
22 | */
23 | this.onPush = 0;
24 |
25 | /**
26 | *
27 | * @var {function(Object)}
28 | */
29 | this.onPushJson = null;
30 | };
31 |
32 | /**
33 | *
34 | * @param {number} connectTimeout unit: s
35 | */
36 | stm.Client.prototype.setConfig = function (connectTimeout){};
37 |
38 | /**
39 | *
40 | * @param {string}url, ws(s)://xxx.xxx.xx:xxx/xxxx
41 | * @param {function()|null} [onSuccess]
42 | * @param {function(string)|null} [onFailed]
43 | */
44 | stm.Client.prototype.setConnectArgs = function(url, onSuccess, onFailed){};
45 |
46 | /**
47 | *
48 | * @param {Object|null} [body]
49 | * @param {function(Object)|null} [onSuccess]
50 | * S
51 | * @param {Object|null} [headers]
52 | * @param {function(string)|null} [onFailed]
53 | * @param {function()|null} [onComplete]
54 | */
55 | stm.Client.prototype.addJsonRequest = function (body, onSuccess, headers, onFailed, onComplete) {};
56 |
57 | /**
58 | *
59 | * @param {ArrayBuffer|string|null} [body]
60 | * @param {function(ArrayBuffer)|null} [onSuccess]
61 | * @param {Object|null} [headers]
62 | * @param {function(string)|null} [onFailed]
63 | * @param {function()|null} [onComplete]
64 | */
65 | stm.Client.prototype.addRequest = function (body, onSuccess, headers, onFailed, onComplete) {};
66 |
--------------------------------------------------------------------------------
/client/ios/test-stm/test-stm/Info.plist:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | CFBundleDevelopmentRegion
6 | en
7 | CFBundleExecutable
8 | $(EXECUTABLE_NAME)
9 | CFBundleIdentifier
10 | $(PRODUCT_BUNDLE_IDENTIFIER)
11 | CFBundleInfoDictionaryVersion
12 | 6.0
13 | CFBundleName
14 | $(PRODUCT_NAME)
15 | CFBundlePackageType
16 | APPL
17 | CFBundleShortVersionString
18 | 1.0
19 | CFBundleSignature
20 | ????
21 | CFBundleVersion
22 | 1
23 | LSRequiresIPhoneOS
24 |
25 | UILaunchStoryboardName
26 | LaunchScreen
27 | UIMainStoryboardFile
28 | Main
29 | UIRequiredDeviceCapabilities
30 |
31 | armv7
32 |
33 | UISupportedInterfaceOrientations
34 |
35 | UIInterfaceOrientationPortrait
36 | UIInterfaceOrientationLandscapeLeft
37 | UIInterfaceOrientationLandscapeRight
38 |
39 | UISupportedInterfaceOrientations~ipad
40 |
41 | UIInterfaceOrientationPortrait
42 | UIInterfaceOrientationPortraitUpsideDown
43 | UIInterfaceOrientationLandscapeLeft
44 | UIInterfaceOrientationLandscapeRight
45 |
46 |
47 |
48 |
--------------------------------------------------------------------------------
/client/ios/test-stm/test-stm/Base.lproj/LaunchScreen.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
--------------------------------------------------------------------------------
/client/ios/STMClient.h:
--------------------------------------------------------------------------------
1 | //
2 | // STMClient.h
3 | // ios-sdk
4 | //
5 | // Created by xpwu on 2016/11/24.
6 | // Copyright © 2016年 xpwu.xpwu. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface STMClient : NSObject
12 |
13 | @property(nonatomic) void (^onpush)(NSData*);
14 |
15 | // unit: s
16 | // default 30s; 4*60s; 10s
17 | -(void)setConfigConnectionTimeout:(NSTimeInterval)ctime_s
18 | heartbeat:(NSTimeInterval)htime_s
19 | transmission:(NSTimeInterval)ttime_s;
20 |
21 |
22 | -(void)setConnectHost:(NSString*)host
23 | port:(uint16_t)port;
24 |
25 | -(void)setConnectHost:(NSString*)host
26 | port:(uint16_t)port
27 | onSuccess:(void (^)(void))suc;
28 |
29 | -(void)setConnectHost:(NSString*)host
30 | port:(uint16_t)port
31 | onSuccess:(void (^)(void))suc
32 | onFailed:(void (^)(NSString*))failed;
33 |
34 |
35 | /**
36 | All args can be set nil;
37 | onSuccess: only callback for successful.
38 | onFailed: only callback for failed
39 | complete: callback wether successful or failed
40 | */
41 |
42 | -(void)addRequestBody:(NSData*)body
43 | onSuccess:(void (^)(NSData*))suc;
44 |
45 | -(void)addRequestBody:(NSData*)body
46 | headers:(NSDictionary*)headers
47 | onSuccess:(void (^)(NSData*))suc;
48 |
49 | -(void)addRequestBody:(NSData*)body
50 | headers:(NSDictionary*)headers
51 | onSuccess:(void (^)(NSData*))suc
52 | onFailed:(void (^)(NSString*))failed;
53 |
54 | -(void)addRequestBody:(NSData*)body
55 | headers:(NSDictionary*)headers
56 | onSuccess:(void (^)(NSData*))suc
57 | onFailed:(void (^)(NSString*))failed
58 | onComplete:(void (^)())complete;
59 |
60 | @end
61 |
--------------------------------------------------------------------------------
/client/ios/out/STMClient.h:
--------------------------------------------------------------------------------
1 | //
2 | // STMClient.h
3 | // ios-sdk
4 | //
5 | // Created by xpwu on 2016/11/24.
6 | // Copyright © 2016年 xpwu.xpwu. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | @interface STMClient : NSObject
12 |
13 | @property(nonatomic) void (^onpush)(NSData*);
14 |
15 | // unit: s
16 | // default 30s; 4*60s; 10s
17 | -(void)setConfigConnectionTimeout:(NSTimeInterval)ctime_s
18 | heartbeat:(NSTimeInterval)htime_s
19 | transmission:(NSTimeInterval)ttime_s;
20 |
21 |
22 | -(void)setConnectHost:(NSString*)host
23 | port:(uint16_t)port;
24 |
25 | -(void)setConnectHost:(NSString*)host
26 | port:(uint16_t)port
27 | onSuccess:(void (^)(void))suc;
28 |
29 | -(void)setConnectHost:(NSString*)host
30 | port:(uint16_t)port
31 | onSuccess:(void (^)(void))suc
32 | onFailed:(void (^)(NSString*))failed;
33 |
34 |
35 | /**
36 | All args can be set nil;
37 | onSuccess: only callback for successful.
38 | onFailed: only callback for failed
39 | complete: callback wether successful or failed
40 | */
41 |
42 | -(void)addRequestBody:(NSData*)body
43 | onSuccess:(void (^)(NSData*))suc;
44 |
45 | -(void)addRequestBody:(NSData*)body
46 | headers:(NSDictionary*)headers
47 | onSuccess:(void (^)(NSData*))suc;
48 |
49 | -(void)addRequestBody:(NSData*)body
50 | headers:(NSDictionary*)headers
51 | onSuccess:(void (^)(NSData*))suc
52 | onFailed:(void (^)(NSString*))failed;
53 |
54 | -(void)addRequestBody:(NSData*)body
55 | headers:(NSDictionary*)headers
56 | onSuccess:(void (^)(NSData*))suc
57 | onFailed:(void (^)(NSString*))failed
58 | onComplete:(void (^)())complete;
59 |
60 | @end
61 |
--------------------------------------------------------------------------------
/client/js/stm.contentprotocol.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by xpwu on 2016/12/1.
3 | */
4 |
5 | (function (ns) {
6 | "use strict";
7 |
8 | var stm = ns.stm = ns.stm || {};
9 |
10 | stm.ContentProtocol = {
11 | /**
12 | *
13 | * @param {function()}callback
14 | */
15 | onOpen: function (callback) {
16 | callback();
17 | }
18 |
19 | /**
20 | *
21 | */
22 | , onClose: function () {
23 |
24 | }
25 |
26 | /**
27 | *
28 | * @param {ArrayBuffer}message
29 | * @return {*|Response}
30 | */
31 | , parse: function (message) {
32 | return new stm.Response();
33 | }
34 |
35 | /**
36 | *
37 | * @param {ArrayBuffer|string|null}body
38 | * @param {Object|null}headers
39 | * @param {number}reqID
40 | * @return {ArrayBuffer|string} success:ArrayBuffer; error: string
41 | */
42 | , build: function (body, headers, reqID) {
43 | return new ArrayBuffer(2);
44 | }
45 |
46 | /**
47 | *
48 | * @param {string}error
49 | * @param {number}reqID
50 | * @return {ArrayBuffer}
51 | */
52 | , buildFailedMessage: function(error, reqID) {
53 | return new ArrayBuffer(2);
54 | }
55 |
56 | , extend: function(child) {
57 | if (child.__proto__) {
58 | child.__proto__ = this;
59 | } else {
60 | for (var propertyName in this) {
61 | if (this.hasOwnProperty(propertyName)
62 | && !child.hasOwnProperty(propertyName)) {
63 | child[propertyName] = this[propertyName];
64 | }
65 | }
66 |
67 | // IE won't copy toString using the loop above
68 | if (this.hasOwnProperty('toString')
69 | && !child.hasOwnProperty('toString')) {
70 | child.toString = this.toString;
71 | }
72 | }
73 | child.$parent = this;
74 |
75 | return child;
76 | }
77 | };
78 |
79 | })(this);
--------------------------------------------------------------------------------
/client/wxapp/stm/contentprotocol.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by xpwu on 2016/12/1.
3 | */
4 |
5 | // (function (ns) {
6 | // "use strict";
7 |
8 | // var stm = ns.stm = ns.stm || {};
9 |
10 | let ContentProtocol = {
11 | /**
12 | *
13 | * @param {function()}callback
14 | */
15 | onOpen: function (callback) {
16 | callback();
17 | }
18 |
19 | /**
20 | *
21 | */
22 | , onClose: function () {
23 |
24 | }
25 |
26 | /**
27 | *
28 | * @param {ArrayBuffer}message
29 | * @return {*|Response}
30 | */
31 | , parse: function (message) {
32 | return new stm.Response();
33 | }
34 |
35 | /**
36 | *
37 | * @param {ArrayBuffer|string|null}body
38 | * @param {Object|null}headers
39 | * @param {number}reqID
40 | * @return {ArrayBuffer|string} success:ArrayBuffer; error: string
41 | */
42 | , build: function (body, headers, reqID) {
43 | return new ArrayBuffer(2);
44 | }
45 |
46 | /**
47 | *
48 | * @param {string}error
49 | * @param {number}reqID
50 | * @return {ArrayBuffer}
51 | */
52 | , buildFailedMessage: function(error, reqID) {
53 | return new ArrayBuffer(2);
54 | }
55 |
56 | , extend: function(child) {
57 | if (child.__proto__) {
58 | child.__proto__ = this;
59 | } else {
60 | for (var propertyName in this) {
61 | if (this.hasOwnProperty(propertyName)
62 | && !child.hasOwnProperty(propertyName)) {
63 | child[propertyName] = this[propertyName];
64 | }
65 | }
66 |
67 | // IE won't copy toString using the loop above
68 | if (this.hasOwnProperty('toString')
69 | && !child.hasOwnProperty('toString')) {
70 | child.toString = this.toString;
71 | }
72 | }
73 | child.$parent = this;
74 |
75 | return child;
76 | }
77 | };
78 |
79 | module.exports.ContentProtocol = ContentProtocol;
80 |
81 | // })(this);
--------------------------------------------------------------------------------
/client/wxapp/stm/client.es6.js:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 | let ClientImpl = require("client").Client;
5 |
6 |
7 | class Client {
8 | constructor() {
9 | /**
10 | *
11 | * @type {Client}
12 | * @private
13 | */
14 | this.impl_ = new ClientImpl();
15 | }
16 |
17 | /**
18 | *
19 | * @return {Promise.}
20 | */
21 | pushJson() {
22 | return new Promise((resolve)=>{
23 | this.impl_.onPushJson = function (json) {
24 | resolve(json);
25 | }
26 | });
27 | }
28 |
29 | /**
30 | *
31 | * @param {number} connectTimeout unit: s
32 | */
33 | setConfig(connectTimeout) {
34 | this.impl_.setConfig(connectTimeout);
35 | }
36 |
37 | /**
38 | *
39 | * @param {string}args ws(s)://xxxxx:xx
40 | * @return {Promise.}
41 | */
42 | setConnectArgs(args) {
43 | return new Promise((resolve, reject)=>{
44 | this.impl_.setConnectArgs(args, ()=>{
45 | resolve();
46 | }, (error)=>{
47 | reject(error);
48 | })
49 | });
50 | }
51 |
52 | /**
53 | *
54 | * @param {{}|null}body
55 | * @param {{}|null}headers
56 | * @return {Promise.}
57 | */
58 | addJsonRequest(body, headers) {
59 | return new Promise((resolve, reject)=>{
60 | this.impl_.addJsonRequest(body, (res)=>{
61 | resolve(res);
62 | }, headers
63 | , (error)=>{
64 | reject(error);
65 | }, null);
66 | });
67 | }
68 |
69 | // /**
70 | // *
71 | // * @param {ArrayBuffer|string|null}body
72 | // * @param {{}|null}headers
73 | // * @return {Promise.}
74 | // */
75 | // addRequest(body, headers) {
76 | // return new Promise((resolve, reject)=>{
77 | // this.impl_.addRequest(body, (res)=>{
78 | // resolve(res);
79 | // }, headers
80 | // , (error)=>{
81 | // reject(error);
82 | // });
83 | // })
84 | // }
85 | }
86 |
87 | module.exports.Client = Client;
88 |
--------------------------------------------------------------------------------
/client/ios/test-stm/test-stm/AppDelegate.m:
--------------------------------------------------------------------------------
1 | //
2 | // AppDelegate.m
3 | // test-stm
4 | //
5 | // Created by xpwu on 2016/12/13.
6 | // Copyright © 2016年 xpwuxpwu. All rights reserved.
7 | //
8 |
9 | #import "AppDelegate.h"
10 |
11 | @interface AppDelegate ()
12 |
13 | @end
14 |
15 | @implementation AppDelegate
16 |
17 |
18 | - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
19 | // Override point for customization after application launch.
20 | return YES;
21 | }
22 |
23 | - (void)applicationWillResignActive:(UIApplication *)application {
24 | // Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
25 | // Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
26 | }
27 |
28 | - (void)applicationDidEnterBackground:(UIApplication *)application {
29 | // Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later.
30 | // If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
31 | }
32 |
33 | - (void)applicationWillEnterForeground:(UIApplication *)application {
34 | // Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
35 | }
36 |
37 | - (void)applicationDidBecomeActive:(UIApplication *)application {
38 | // Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
39 | }
40 |
41 | - (void)applicationWillTerminate:(UIApplication *)application {
42 | // Called when the application is about to terminate. Save data if appropriate. See also applicationDidEnterBackground:.
43 | }
44 |
45 | @end
46 |
--------------------------------------------------------------------------------
/client/ios/test-stm/test-stm/Base.lproj/Main.storyboard:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 |
--------------------------------------------------------------------------------
/stream_module/ngx_stream_request_cut_frame_module/ngx_stream_request_cut_frame_module.c:
--------------------------------------------------------------------------------
1 | //
2 | // ngx_stream_request_cut_frame_module.c
3 | // nginx-1.12
4 | //
5 | // Created by xpwu on 2019/1/31.
6 | // Copyright © 2019 xpwu. All rights reserved.
7 | //
8 |
9 | #include
10 | #include
11 | #include
12 |
13 | #define PROTOCOL_RESPONSE_SUCCESS 0
14 | #define PROTOCOL_RESPONSE_FAILED 1
15 |
16 | #ifdef this_module
17 | #undef this_module
18 | #endif
19 | #define this_module ngx_stream_request_cut_frame_module
20 |
21 | #ifdef core_module
22 | #undef core_module
23 | #endif
24 | #define core_module ngx_stream_request_core_module
25 |
26 | static void *ngx_stream_cut_frame_create_srv_conf(ngx_conf_t *cf);
27 | static char *ngx_stream_cut_frame_merge_srv_conf(ngx_conf_t *cf
28 | , void *parent, void *child);
29 | char *cut_frame_conf(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
30 |
31 |
32 | static ngx_command_t ngx_stream_cut_frame_commands[] = {
33 |
34 | { ngx_string("cut_frame_protocol"),
35 | NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_NOARGS,
36 | cut_frame_conf,
37 | NGX_STREAM_SRV_CONF_OFFSET,
38 | 0,
39 | NULL },
40 |
41 |
42 | ngx_null_command
43 | };
44 |
45 |
46 | static ngx_stream_module_t ngx_stream_cut_frame_module_ctx = {
47 | NULL,
48 | NULL, /* postconfiguration */
49 |
50 | NULL, /* create main configuration */
51 | NULL, /* init main configuration */
52 |
53 | ngx_stream_cut_frame_create_srv_conf, /* create server configuration */
54 | ngx_stream_cut_frame_merge_srv_conf /* merge server configuration */
55 | };
56 |
57 | ngx_module_t ngx_stream_request_cut_frame_module = {
58 | NGX_MODULE_V1,
59 | &ngx_stream_cut_frame_module_ctx, /* module context */
60 | ngx_stream_cut_frame_commands, /* module directives */
61 | NGX_STREAM_MODULE, /* module type */
62 | NULL, /* init master */
63 | NULL, /* init module */
64 | NULL, /* init process */
65 | NULL, /* init thread */
66 | NULL, /* exit thread */
67 | NULL, /* exit process */
68 | NULL, /* exit master */
69 | NGX_MODULE_V1_PADDING
70 | };
71 |
72 |
73 | // heartbeat
74 | typedef void (*start_heartbeat_timer)();
75 | typedef void (*clear_heartbeat_timer_after_send_else)();
76 | typedef void (*clear_heartbeat_timer)();
77 | typedef void (*send_heartbeat)();
78 |
79 | typedef struct {
80 | start_heartbeat_timer start;
81 | clear_heartbeat_timer_after_send_else clear_after_else;
82 | clear_heartbeat_timer clear;
83 | send_heartbeat send;
84 | } heartbeart;
85 |
86 |
87 |
88 |
89 |
90 |
--------------------------------------------------------------------------------
/push/php/Pusher.inc:
--------------------------------------------------------------------------------
1 |
15 | * sizeof(sequece) = 4. net order
16 | * sizeof(token) = 32 . hex
17 | * sizeof(subprotocol) = 1.
18 | * sizeof(len) = 4. len = sizof(data) net order
19 | * data: subprotocol request data
20 | *
21 | * response:
22 | * sequece | state | len |
23 | * sizeof(sequece) = 4. net order
24 | * sizeof(state) = 1.
25 | * state = 0: success; 1: hostname error
26 | * ; 2: token not exist; 3: server intelnal error
27 | * sizeof(len) = 4. len = sizeof(data) net order
28 | * data: subprotocol response data
29 | */
30 |
31 | abstract class Pusher {
32 |
33 | function __construct(int $subProtocol) {
34 | $this->subProtocol_ = $subProtocol;
35 | }
36 |
37 | /**
38 | * @param string $sessionToken [host:port/sessiontoken]
39 | * @return int
40 | */
41 | public function pushTo(string $url): int {
42 | $re = parse_url($url);
43 | if ($re === false || !$re["host"] || !$re["port"] || !$re["path"]) {
44 | return PushState::UrlError;
45 | }
46 |
47 | if (!$this->fd($re["host"], $re["port"])) {
48 | return PushState::HostConnectionError;
49 | }
50 |
51 | $sessionToken = substr($re["path"], 1); // trim the first '/'
52 |
53 | $seq = time();
54 | $data = $this->subProtocolData();
55 |
56 | $request = pack("N", $seq).$sessionToken.pack("C", $this->subProtocol_)
57 | .pack("N", strlen($data)).$data;
58 |
59 | $fd = $this->fd_;
60 |
61 | stream_set_timeout($fd, 5);
62 | if (!fwrite($fd, $request)) {
63 | return PushState::ElseError;
64 | }
65 | $status = stream_get_meta_data($this->fd_);
66 | if ($status['timed_out']) {
67 | return PushState::PushTimeout;
68 | }
69 |
70 | stream_set_timeout($fd, 5);
71 | $res = fread($fd, 9);
72 | if (!$res) {
73 | return PushState::ElseError;
74 | }
75 | $response = unpack("Nseq/Cst/Nlen", $res);
76 | $status = stream_get_meta_data($this->fd_);
77 | if ($status['timed_out']) {
78 | return PushState::PushTimeout;
79 | }
80 |
81 | if ($seq != $response["seq"]) {
82 | return PushState::PushServerError;
83 | }
84 | if ($response["len"] !== 0) {
85 | $this->result_ = fread($fd, $response["len"]);
86 | }
87 |
88 | return $response["st"];
89 | }
90 |
91 | private function fd(string $host, int $port):bool {
92 | try {
93 | $this->fd_ = fsockopen($host, $port, $errNO, $errStr, 10);
94 | }catch (\Exception $e) {
95 | return false;
96 | }
97 | return true;
98 | }
99 |
100 | abstract protected function subProtocolData():string ;
101 |
102 | public function result():string {
103 | return $this->result_;
104 | }
105 |
106 | private $fd_;
107 | private $result_="";
108 | private $subProtocol_;
109 |
110 | }
--------------------------------------------------------------------------------
/client/js/test/test.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | test js
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | this is only test stm.client.
19 |
110 |
111 |
--------------------------------------------------------------------------------
/stream_module/ngx_stream_request_core_module/ngx_stream_request.c:
--------------------------------------------------------------------------------
1 | //
2 | // ngx_stream_request.c
3 | // nginx-1.12
4 | //
5 | // Created by xpwu on 2017/12/16.
6 | // Copyright © 2017年 xpwu. All rights reserved.
7 | //
8 |
9 | #include
10 |
11 | extern void ngx_stream_request_regular_data(ngx_stream_request_t* r) {
12 | if (r->data == NULL) {
13 | return;
14 | }
15 | ngx_chain_t* chain = NULL, *prev=NULL;
16 | for (chain = r->data->next, prev = r->data
17 | ; chain != NULL; chain=chain->next) {
18 | if (ngx_buf_size(chain->buf) == 0) {
19 | prev->next = chain->next;
20 | } else {
21 | prev = chain;
22 | }
23 | }
24 | if (ngx_buf_size(r->data->buf) == 0) {
25 | r->data = r->data->next;
26 | }
27 | }
28 |
29 | extern void ngx_stream_request_set_data(ngx_stream_request_t* r, char* err_info) {
30 | ngx_int_t len = ngx_strlen(err_info);
31 |
32 | r->data->buf = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
33 | r->data->buf = ngx_create_temp_buf(r->pool, len);
34 | r->data->next = NULL;
35 | ngx_memcpy(r->data->buf->last, err_info, len);
36 | r->data->buf->last += len;
37 | }
38 |
39 | extern ngx_uint_t ngx_chain_len(ngx_chain_t* chain) {
40 | ngx_uint_t len = 0;
41 | for (; chain != NULL; chain = chain->next) {
42 | len += chain->buf->last - chain->buf->pos;
43 | }
44 | return len;
45 | }
46 |
47 | extern void ngx_regular_buf(ngx_buf_t* buf) {
48 | off_t size = ngx_buf_size(buf);
49 | if (size != 0) {
50 | ngx_memmove(buf->start, buf->pos, size);
51 | }
52 | buf->pos = buf->start;
53 | buf->last = buf->pos + size;
54 | }
55 |
56 | static ngx_int_t is_equal_str(ngx_str_t* str1, ngx_str_t* str2) {
57 | if (str1->len != str2->len) {
58 | return 0;
59 | }
60 | if (0 != ngx_strncmp(str1->data, str2->data, str2->len)) {
61 | return 0;
62 | }
63 | return 1;
64 | }
65 |
66 | extern ngx_array_t* ngx_merge_key_val_array(ngx_pool_t* pool, ngx_array_t* parent
67 | , ngx_array_t* child) {
68 |
69 | if (parent == NULL && child == NULL) {
70 | return NULL;
71 | }
72 | ngx_int_t len = 0;
73 | if (parent != NULL) {
74 | len += parent->nelts;
75 | }
76 | if (child != NULL) {
77 | len += child->nelts;
78 | }
79 | ngx_array_t* re = ngx_array_create(pool, len
80 | , sizeof(ngx_keyval_t));
81 |
82 | ngx_array_t* arrs[2];
83 | arrs[0] = parent;
84 | arrs[1] = child;
85 |
86 | ngx_int_t i = 0;
87 | for (i = 1; i >= 0; --i) {
88 | if (arrs[i] == NULL) {
89 | continue;
90 | }
91 |
92 | ngx_keyval_t* elts = arrs[i]->elts;
93 | ngx_uint_t j = arrs[i]->nelts;
94 | for (; j > 0; --j) {
95 | int contin = 0;
96 |
97 | ngx_uint_t k = 0;
98 | ngx_keyval_t* res = re->elts;
99 | for (; k < re->nelts; ++k) {
100 | if (1 == is_equal_str(&res[k].key, &elts[j-1].key)) {
101 | contin = 1;
102 | break;
103 | }
104 | }
105 | if (contin) {
106 | continue;
107 | }
108 | res = ngx_array_push(re);
109 | res->key = elts[j-1].key;
110 | res->value = elts[j-1].value;
111 | }
112 | }
113 |
114 | return re;
115 | }
116 |
117 |
118 |
119 |
--------------------------------------------------------------------------------
/client/js/test/test.min.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | test js
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 | this is only test stm.client.min
16 |
119 |
120 |
--------------------------------------------------------------------------------
/client/js/test/test.ssl.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 | test ssl js
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 | this is only test stm.client.ssl
19 |
122 |
123 |
--------------------------------------------------------------------------------
/client/js/stm.defaultcontentprotocol.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by xpwu on 2016/12/1.
3 | */
4 |
5 |
6 | (function (ns) {
7 | "use strict";
8 | var stm = ns.stm = ns.stm || {};
9 |
10 | stm.DefaultContentProtocol = {
11 | /**
12 | *
13 | * @param {ArrayBuffer} message
14 | * @return {*|Response}
15 | */
16 | parse: function (message) {
17 | var response = new stm.Response();
18 | var messageView = new DataView(message);
19 | response.reqID = messageView.getUint32(0);
20 | response.state = (messageView.getUint8(4) == 0)? stm.Response.State.Success
21 | : stm.Response.State.Failed;
22 | response.data = message.slice(5);
23 |
24 | return response;
25 | }
26 |
27 | /**
28 | *
29 | * @param {ArrayBuffer|string|null}body
30 | * @param {Object|null}headers
31 | * @param {number}reqID
32 | * @return {ArrayBuffer|string}
33 | */
34 | , build: function (body, headers, reqID) {
35 | body = body || "";
36 | if (typeof body !== "string" && !(body instanceof ArrayBuffer)) {
37 | return "body type is error, must be string or ArrayBuffer";
38 | }
39 |
40 | headers = headers || {};
41 | if (typeof headers !== "object") {
42 | return "headers must be a object type, for example {uri: '/location'}";
43 | }
44 |
45 | var headerLen = 0;
46 | for (var key in headers) {
47 | if (!headers.hasOwnProperty(key)) {
48 | continue;
49 | }
50 | if (typeof key !== "string" || typeof headers[key] !== "string") {
51 | return "headers' key or property must be string";
52 | }
53 |
54 | if (key.length > 255) {
55 | return "length of headers' key <" + key + "> more than 255";
56 | }
57 | if (headers[key].length > 255) {
58 | return "length of headers' object <" + headers[key] + "> more than 255";
59 | }
60 |
61 | if (key.length == 0 || headers[key].length == 0) {
62 | continue;
63 | }
64 | headerLen += 1 + 1 + key.length + headers[key].length;
65 | }
66 |
67 | body = new StringView(body);
68 | var buffer = new ArrayBuffer(4 + body.rawData.byteLength + 1 + headerLen);
69 | (new DataView(buffer)).setUint32(0, reqID);
70 |
71 | var pos = 4;
72 | for (key in headers) {
73 | if (!headers.hasOwnProperty(key)) {
74 | continue;
75 | }
76 |
77 | (new DataView(buffer)).setUint8(pos, key.length);
78 | pos++;
79 | (new Uint8Array(buffer)).set((new StringView(key)).rawData, pos);
80 | pos += key.length;
81 | (new DataView(buffer)).setUint8(pos, headers[key].length);
82 | pos++;
83 | (new Uint8Array(buffer)).set((new StringView(headers[key])).rawData, pos);
84 | pos += headers[key].length;
85 | }
86 | (new DataView(buffer)).setUint8(pos, 0);
87 | pos++;
88 |
89 | (new Uint8Array(buffer)).set(body.rawData, pos);
90 |
91 | return buffer;
92 | }
93 |
94 | /**
95 | *
96 | * @param {string}error
97 | * @param {number}reqID
98 | * @return {ArrayBuffer}
99 | */
100 | , buildFailedMessage: function(error, reqID) {
101 |
102 | error = new StringView(error);
103 | var buffer = new ArrayBuffer(4 + error.rawData.byteLength + 1);
104 | (new DataView(buffer)).setUint32(0, reqID);
105 | (new DataView(buffer)).setUint8(4, stm.Response.State.Failed);
106 | (new Uint8Array(buffer)).set(error.rawData, 5);
107 |
108 | return buffer;
109 | }
110 |
111 | };
112 |
113 | })(this);
114 |
--------------------------------------------------------------------------------
/client/ios/compile/Makefile.am:
--------------------------------------------------------------------------------
1 | ACLOCAL_AMFLAGS=-I m4
2 | ##AUTOMAKE_OPTIONS = subdir-objects
3 | AUTOMAKE_OPTIONS = --warnings=none
4 |
5 | noinst_LIBRARIES = libclient_armv7s.a libclient_armv7.a libclient_arm64.a \
6 | libclient_i386.a libclient_x64.a
7 | #noinst_PROGRAMS = stmclient
8 |
9 |
10 | INCLUDES = -I ${top_srcdir}/..
11 |
12 | MODE=release
13 | MODE_FLAGS=-DNDEBUG
14 | CXXFLAGS=-O2
15 | CFLAGS=-O2
16 |
17 | # ##---ios var
18 | IOS_MIN_SDK=7.0
19 | ##IPHONEOS_SYSROOT=""
20 | ##IPHONESIMULATOR_SYSROOT=""
21 | if MACOS
22 | XCODEDIR=/Applications/Xcode.app/Contents/Developer
23 | IPHONEOS_SYSROOT=${XCODEDIR}/Platforms/iPhoneOS.platform/Developer/SDKs/iPhoneOS.sdk
24 | IPHONESIMULATOR_SYSROOT=${XCODEDIR}/Platforms/iPhoneSimulator.platform/Developer/SDKs/iPhoneSimulator.sdk
25 | else
26 | endif
27 |
28 | COM_CFLAGS=$(MODE_FLAGS) -pipe -fPIC -fobjc-arc -miphoneos-version-min=$(IOS_MIN_SDK)# -fcxx-exceptions
29 | IOS_CFLAGS=-isysroot $(IPHONEOS_SYSROOT) $(COM_CFLAGS) -fembed-bitcode
30 | SIM_CFLAGS=-isysroot ${IPHONESIMULATOR_SYSROOT} $(COM_CFLAGS)
31 | IOS_OBJCFLAGS=${IOS_CFLAGS}
32 | SIM_OBJCFLAGS=${SIM_CFLAGS}
33 | COM_CXXFLAGS=-std=c++11 -stdlib=libc++
34 | IOS_CXXFLAGS=${IOS_CFLAGS} $(COM_CXXFLAGS)
35 | SIM_CXXFLAGS=${SIM_CFLAGS} $(COM_CXXFLAGS)
36 | IOS_OBJCXXFLAGS=${IOS_CXXFLAGS}
37 | SIM_OBJCXXFLAGS=${SIM_CXXFLAGS}
38 |
39 |
40 | # ##---ios var end
41 |
42 |
43 | ios_common_SOURCES= ${top_srcdir}/../STMClient.m \
44 | ${top_srcdir}/../STMDefaultContentProtocol.m \
45 | ${top_srcdir}/../STMNet.mm \
46 | ${top_srcdir}/../STMResponse.m
47 |
48 | libclient_armv7s_a_SOURCES = $(ios_common_SOURCES)
49 | libclient_armv7s_a_CXXFLAGS=$(IOS_CXXFLAGS) -arch armv7s
50 | libclient_armv7s_a_OBJCXXFLAGS=$(IOS_OBJCXXFLAGS) -arch armv7s
51 | libclient_armv7s_a_OBJCFLAGS=$(IOS_OBJCFLAGS) -arch armv7s
52 |
53 | libclient_armv7_a_SOURCES = $(ios_common_SOURCES)
54 | libclient_armv7_a_CXXFLAGS=$(IOS_CXXFLAGS) -arch armv7
55 | libclient_armv7_a_OBJCXXFLAGS=$(IOS_OBJCXXFLAGS) -arch armv7
56 | libclient_armv7_a_OBJCFLAGS=$(IOS_OBJCFLAGS) -arch armv7
57 |
58 | libclient_arm64_a_SOURCES = $(ios_common_SOURCES)
59 | libclient_arm64_a_CXXFLAGS=$(IOS_CXXFLAGS) -arch arm64
60 | libclient_arm64_a_OBJCXXFLAGS=$(IOS_OBJCXXFLAGS) -arch arm64
61 | libclient_arm64_a_OBJCFLAGS=$(IOS_OBJCFLAGS) -arch arm64
62 |
63 | libclient_i386_a_SOURCES = $(ios_common_SOURCES)
64 | libclient_i386_a_CXXFLAGS=$(SIM_CXXFLAGS) -arch i386
65 | libclient_i386_a_OBJCXXFLAGS=$(SIM_OBJCXXFLAGS) -arch i386
66 | libclient_i386_a_OBJCFLAGS=$(SIM_OBJCFLAGS) -arch i386
67 |
68 | libclient_x64_a_SOURCES = $(ios_common_SOURCES)
69 | libclient_x64_a_CXXFLAGS=$(SIM_CXXFLAGS) -arch x86_64
70 | libclient_x64_a_OBJCXXFLAGS=$(SIM_OBJCXXFLAGS) -arch x86_64
71 | libclient_x64_a_OBJCFLAGS=$(SIM_OBJCFLAGS) -arch x86_64
72 |
73 | #stmclient_SOURCES = ${top_srcdir}/../ios-sdk/ios-sdk/main.m
74 | #stmclient_OBJCFLAGS = $(MODE_FLAGS) -isysroot ${XCODEDIR}/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.11.sdk
75 | #stmclient_LDFLAGS = -framework Foundation
76 | #stmclient_LDADD = ${top_srcdir}/../out/$(MODE)/libstmclient.a
77 |
78 | all-local:libclient_armv7.a libclient_arm64.a libclient_i386.a libclient_x64.a libclient_armv7s.a # stmclient
79 | @if ! [ -d ${top_srcdir}/../out/$(MODE) ] ;then \
80 | mkdir -p ${top_srcdir}/../out/$(MODE); \
81 | fi
82 | lipo -create libclient_armv7.a libclient_arm64.a libclient_i386.a libclient_x64.a libclient_armv7s.a \
83 | -output ${top_srcdir}/../out/$(MODE)/libstmclient.a
84 | @cp ${top_srcdir}/../STMClient.h ${top_srcdir}/../out/STMClient.h
85 | # @cp stmclient ${top_srcdir}/../out/$(MODE)/stmclient
86 | @echo "BUILD SUCCESS ---out/$(MODE)"
87 |
88 |
89 | debug:
90 | $(MAKE) all CFLAGS="-g" CXXFLAGS="-g" MODE="debug" MODE_FLAGS="-DDEBUG"
91 |
92 |
93 |
--------------------------------------------------------------------------------
/client/java/.idea/codeStyles/Project.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
11 |
12 |
13 | xmlns:android
14 |
15 | ^$
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | xmlns:.*
25 |
26 | ^$
27 |
28 |
29 | BY_NAME
30 |
31 |
32 |
33 |
34 |
35 |
36 | .*:id
37 |
38 | http://schemas.android.com/apk/res/android
39 |
40 |
41 |
42 |
43 |
44 |
45 |
46 |
47 | .*:name
48 |
49 | http://schemas.android.com/apk/res/android
50 |
51 |
52 |
53 |
54 |
55 |
56 |
57 |
58 | name
59 |
60 | ^$
61 |
62 |
63 |
64 |
65 |
66 |
67 |
68 |
69 | style
70 |
71 | ^$
72 |
73 |
74 |
75 |
76 |
77 |
78 |
79 |
80 | .*
81 |
82 | ^$
83 |
84 |
85 | BY_NAME
86 |
87 |
88 |
89 |
90 |
91 |
92 | .*
93 |
94 | http://schemas.android.com/apk/res/android
95 |
96 |
97 | ANDROID_ATTRIBUTE_ORDER
98 |
99 |
100 |
101 |
102 |
103 |
104 | .*
105 |
106 | .*
107 |
108 |
109 | BY_NAME
110 |
111 |
112 |
113 |
114 |
115 |
116 |
--------------------------------------------------------------------------------
/client/wxapp/stm/defaultcontentprotocol.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by xpwu on 2016/12/1.
3 | */
4 |
5 |
6 | // (function (ns) {
7 | // "use strict";
8 | // var stm = ns.stm = ns.stm || {};
9 |
10 | let StringView = require("stringview.js").StringView;
11 | let Response = require("response.js").Response;
12 | let WXWebSocket = require("wxwebsocket.js").WXWebSocket;
13 |
14 | let stm={};
15 | stm.Response = Response;
16 | stm.StringView = StringView;
17 |
18 | let DefaultContentProtocol = {
19 | /**
20 | *
21 | * @param {ArrayBuffer} message
22 | * @return {*|Response}
23 | */
24 | parse: function (message) {
25 | var response = new stm.Response();
26 | var messageView = new DataView(message);
27 | response.reqID = messageView.getUint32(0);
28 | response.state = (messageView.getUint8(4) == 0)? stm.Response.State.Success
29 | : stm.Response.State.Failed;
30 | response.data = message.slice(5);
31 |
32 | return response;
33 | }
34 |
35 | /**
36 | *
37 | * @param {ArrayBuffer|string|null}body
38 | * @param {Object|null}headers
39 | * @param {number}reqID
40 | * @return {ArrayBuffer|string}
41 | */
42 | , build: function (body, headers, reqID) {
43 | body = body || "";
44 | if (typeof body !== "string" && !(body instanceof ArrayBuffer)) {
45 | return "body type is error, must be string or ArrayBuffer";
46 | }
47 |
48 | headers = headers || {};
49 | if (typeof headers !== "object") {
50 | return "headers must be a object type, for example {uri: '/location'}";
51 | }
52 |
53 | var headerLen = 0;
54 | for (var key in headers) {
55 | if (!headers.hasOwnProperty(key)) {
56 | continue;
57 | }
58 | if (typeof key !== "string" || typeof headers[key] !== "string") {
59 | return "headers' key or property must be string";
60 | }
61 |
62 | if (key.length > 255) {
63 | return "length of headers' key <" + key + "> more than 255";
64 | }
65 | if (headers[key].length > 255) {
66 | return "length of headers' object <" + headers[key] + "> more than 255";
67 | }
68 |
69 | if (key.length == 0 || headers[key].length == 0) {
70 | continue;
71 | }
72 | headerLen += 1 + 1 + key.length + headers[key].length;
73 | }
74 |
75 | body = new StringView(body);
76 | var buffer = new ArrayBuffer(4 + body.rawData.byteLength + 1 + headerLen);
77 | (new DataView(buffer)).setUint32(0, reqID);
78 |
79 | var pos = 4;
80 | for (key in headers) {
81 | if (!headers.hasOwnProperty(key)) {
82 | continue;
83 | }
84 |
85 | (new DataView(buffer)).setUint8(pos, key.length);
86 | pos++;
87 | (new Uint8Array(buffer)).set((new StringView(key)).rawData, pos);
88 | pos += key.length;
89 | (new DataView(buffer)).setUint8(pos, headers[key].length);
90 | pos++;
91 | (new Uint8Array(buffer)).set((new StringView(headers[key])).rawData, pos);
92 | pos += headers[key].length;
93 | }
94 | (new DataView(buffer)).setUint8(pos, 0);
95 | pos++;
96 |
97 | (new Uint8Array(buffer)).set(body.rawData, pos);
98 |
99 | return buffer;
100 | }
101 |
102 | /**
103 | *
104 | * @param {string}error
105 | * @param {number}reqID
106 | * @return {ArrayBuffer}
107 | */
108 | , buildFailedMessage: function(error, reqID) {
109 |
110 | error = new StringView(error);
111 | var buffer = new ArrayBuffer(4 + error.rawData.byteLength + 1);
112 | (new DataView(buffer)).setUint32(0, reqID);
113 | (new DataView(buffer)).setUint8(4, stm.Response.State.Failed);
114 | (new Uint8Array(buffer)).set(error.rawData, 5);
115 |
116 | return buffer;
117 | }
118 |
119 | };
120 |
121 | module.exports.DefaultContentProtocol = DefaultContentProtocol;
122 |
123 | // })(this);
124 |
--------------------------------------------------------------------------------
/client/wxapp/stm/wxwebsocket.js:
--------------------------------------------------------------------------------
1 |
2 |
3 | function TranVersion(vstr) {
4 | let ver = vstr.split(".");
5 | let version = 0;
6 | let factor = 1;
7 | for(let i = ver.length; i > 0; --i) {
8 | version += ver[i-1] * factor;
9 | factor *= 100;
10 | }
11 |
12 | return version;
13 | }
14 |
15 | class WxWebSocketImpl {
16 | constructor() {
17 | this.onmessage = function(data){};
18 | this.onopen = function(data){};
19 | this.onclose = function(data){};
20 | this.onerror = function(data){};
21 |
22 | this.readyState = WXWebSocket.CONNECTING;
23 | }
24 |
25 | /**
26 | @param {String|ArrayBuffer|ArrayBufferView|Blob} msg
27 | */
28 | send(msg){}
29 |
30 | /**
31 | @param {number} [code]
32 | @param {string} [reason]
33 | */
34 | close(code, reason){}
35 | }
36 |
37 | class WxWebSocketImplless170 extends WxWebSocketImpl {
38 | constructor(url) {
39 | super();
40 |
41 | wx.connectSocket({
42 | url: url
43 | });
44 |
45 | wx.onSocketOpen((res)=>{
46 | this.readyState = WXWebSocket.OPEN;
47 | this.onopen(res);
48 | });
49 |
50 | wx.onSocketError((res)=>{
51 | this.readyState = WXWebSocket.CLOSED;
52 | this.onerror(res);
53 | });
54 |
55 | wx.onSocketMessage((res)=>{
56 | this.onmessage(res);
57 | });
58 |
59 | wx.onSocketClose((res)=>{
60 | this.readyState = WXWebSocket.CLOSED;
61 | this.onclose(res);
62 | });
63 | }
64 |
65 | send(msg) {
66 | wx.sendSocketMessage({
67 | data: msg
68 | });
69 | }
70 |
71 | close(code,reason) {
72 | wx.closeSocket({code:code, reason:reason});
73 | };
74 | }
75 |
76 | class WxWebSocketImpl170 extends WxWebSocketImpl {
77 | constructor(url) {
78 | super();
79 |
80 | this.task = wx.connectSocket({
81 | url: url
82 | });
83 |
84 | this.task.onOpen((res)=>{
85 | this.readyState = WXWebSocket.OPEN;
86 | this.onopen(res);
87 | });
88 |
89 | this.task.onClose((res)=>{
90 | this.readyState = WXWebSocket.CLOSED;
91 | this.onclose(res);
92 | });
93 |
94 | this.task.onError((res)=>{
95 | this.readyState = WXWebSocket.CLOSED;
96 | this.onerror(res);
97 | });
98 |
99 | this.task.onMessage((res)=>{
100 | this.onmessage(res);
101 | });
102 | }
103 |
104 | send(msg) {
105 | this.task.send({
106 | data: msg
107 | });
108 | }
109 |
110 | close(code,reason) {
111 | this.task.close({code:code, reason:reason});
112 | };
113 | }
114 |
115 |
116 | class WXWebSocket {
117 |
118 | constructor(url) {
119 | let res = wx.getSystemInfoSync();
120 | if (res.SDKVersion && TranVersion(res.SDKVersion) >= 10700) {
121 | this.impl_ = new WxWebSocketImpl170(url);
122 | } else {
123 | this.impl_ = new WxWebSocketImplless170(url);
124 | }
125 | }
126 |
127 | set onmessage(f) {
128 | this.impl_.onmessage = f;
129 | }
130 |
131 | set onopen(f) {
132 | this.impl_.onopen = f;
133 | }
134 |
135 | set onclose(f) {
136 | this.impl_.onclose = f;
137 | }
138 |
139 | set onerror(f) {
140 | this.impl_.onerror = f;
141 | }
142 |
143 | get readyState() {
144 | return this.impl_.readyState;
145 | }
146 |
147 | /**
148 | @param {String|ArrayBuffer|ArrayBufferView|Blob} msg
149 | */
150 | send(msg) {
151 | this.impl_.send(msg);
152 | };
153 |
154 | /**
155 | @param {number} [code]
156 | @param {string} [reason]
157 | */
158 | close(code,reason) {
159 | this.impl_.close(code, reason);
160 | };
161 | }
162 |
163 | /**
164 | @static
165 | @type {number}
166 | @const
167 | */
168 | WXWebSocket.CONNECTING = 0;
169 | /**
170 | @static
171 | @type {number}
172 | @const
173 | */
174 | WXWebSocket.OPEN = 1;
175 | /**
176 | @static
177 | @type {number}
178 | @const
179 | */
180 | WXWebSocket.CLOSING = 2;
181 | /**
182 | @static
183 | @type {number}
184 | @const
185 | */
186 | WXWebSocket.CLOSED = 3;
187 |
188 |
189 | module.exports.WXWebSocket = WXWebSocket;
190 |
--------------------------------------------------------------------------------
/nginx.conf:
--------------------------------------------------------------------------------
1 |
2 | #user nobody;
3 | worker_processes 4;
4 |
5 | #error_log logs/error.log;
6 | #error_log logs/error.log notice;
7 | #error_log logs/error.log info;
8 |
9 | #pid logs/nginx.pid;
10 |
11 | #daemon off;
12 | #master_process off;
13 |
14 | events {
15 | worker_connections 1024;
16 | }
17 |
18 |
19 | http {
20 | include mime.types;
21 | default_type application/octet-stream;
22 |
23 | #log_format main '$remote_addr - $remote_user [$time_local] "$request" '
24 | # '$status $body_bytes_sent "$http_referer" '
25 | # '"$http_user_agent" "$http_x_forwarded_for"';
26 |
27 | #access_log logs/access.log main;
28 |
29 | sendfile on;
30 | #tcp_nopush on;
31 |
32 | #keepalive_timeout 0;
33 | keepalive_timeout 65;
34 |
35 | #gzip on;
36 |
37 | server {
38 | listen 10000;
39 | server_name localhost;
40 |
41 | #charset koi8-r;
42 |
43 | #access_log logs/host.access.log main;
44 |
45 | location / {
46 | root html;
47 | index index.html index.htm;
48 | add_header Test-Http-pr "text/plain;charset=utf-8";
49 | return 200 "this is test";
50 | }
51 |
52 | #error_page 404 /404.html;
53 |
54 | # redirect server error pages to the static page /50x.html
55 | #
56 | error_page 500 502 503 504 /50x.html;
57 | location = /50x.html {
58 | root html;
59 | }
60 |
61 | # proxy the PHP scripts to Apache listening on 127.0.0.1:80
62 | #
63 | #location ~ \.php$ {
64 | # proxy_pass http://127.0.0.1;
65 | #}
66 |
67 | # pass the PHP scripts to FastCGI server listening on 127.0.0.1:9000
68 | #
69 | #location ~ \.php$ {
70 | # root html;
71 | # fastcgi_pass 127.0.0.1:9000;
72 | # fastcgi_index index.php;
73 | # fastcgi_param SCRIPT_FILENAME /scripts$fastcgi_script_name;
74 | # include fastcgi_params;
75 | #}
76 |
77 | # deny access to .htaccess files, if Apache's document root
78 | # concurs with nginx's one
79 | #
80 | #location ~ /\.ht {
81 | # deny all;
82 | #}
83 | }
84 |
85 |
86 | # another virtual host using mix of IP-, name-, and port-based configuration
87 | #
88 | #server {
89 | # listen 8000;
90 | # listen somename:8080;
91 | # server_name somename alias another.alias;
92 |
93 | # location / {
94 | # root html;
95 | # index index.html index.htm;
96 | # }
97 | #}
98 |
99 |
100 | # HTTPS server
101 | #
102 | #server {
103 | # listen 443 ssl;
104 | # server_name localhost;
105 |
106 | # ssl_certificate cert.pem;
107 | # ssl_certificate_key cert.key;
108 |
109 | # ssl_session_cache shared:SSL:1m;
110 | # ssl_session_timeout 5m;
111 |
112 | # ssl_ciphers HIGH:!aNULL:!MD5;
113 | # ssl_prefer_server_ciphers on;
114 |
115 | # location / {
116 | # root html;
117 | # index index.html index.htm;
118 | # }
119 | #}
120 | }
121 |
122 | stream {
123 | error_log logs/stream.log info;
124 |
125 | server {
126 | listen 7999;
127 | push_protocol;
128 | push_data_subprotocol 0;
129 | push_close_session_subprotocol 1;
130 | }
131 | server {
132 | listen 8000;
133 | lencontent_protocol;
134 | fake_http_subprotocol;
135 | http_proxy_pass 127.0.0.1:10000/$fhttp_api;
136 | http_proxy_last_uri /CloseSession;
137 | http_proxy_add_header PushUrl 127.0.0.1:7999/$sessiontoken;
138 | }
139 | server {
140 | listen 8001;
141 | websocket_protocol;
142 | fake_http_subprotocol;
143 | http_proxy_pass 127.0.0.1:10000/$fhttp_api;
144 | http_proxy_last_uri /CloseSession;
145 | http_proxy_add_header PushUrl 127.0.0.1:7999/$sessiontoken;
146 | }
147 | }
148 |
149 |
--------------------------------------------------------------------------------
/client/ios/STMDefaultContentProtocol.m:
--------------------------------------------------------------------------------
1 | //
2 | // STMDefaultContentProtocol.m
3 | // ios-sdk
4 | //
5 | // Created by xpwu on 2016/11/24.
6 | // Copyright © 2016年 xpwu.xpwu. All rights reserved.
7 | //
8 |
9 | #import "STMDefaultContentProtocol.h"
10 |
11 | #import "Log.h"
12 |
13 | /*
14 | * content protocol:
15 | * request ---
16 | * reqid | headers | header-end-flag | data
17 | * reqid: 4 bytes, net order;
18 | * headers: < key-len | key | value-len | value > ... ; [optional]
19 | * key-len: 1 byte, key-len = sizeof(key);
20 | * value-len: 1 byte, value-len = sizeof(value);
21 | * header-end-flag: 1 byte, === 0; [optional]
22 | * data: [optional]
23 | *
24 | * response ---
25 | * reqid | status | data
26 | * reqid: 4 bytes, net order;
27 | * status: 1 byte, 0---success, 1---failed
28 | * data: if status==success, data= [optional]
29 | * if status==failed, data=
30 | *
31 | */
32 |
33 | @implementation STMDefaultContentProtocol
34 |
35 | #pragma mark - ContentProtocol
36 |
37 | -(void)onopen:(void (^)(void))callback {
38 | if (callback != nil) {
39 | callback();
40 | }
41 | }
42 |
43 | -(void)onclose {}
44 |
45 | -(STMResponse*)parse:(NSData*)message {
46 | const uint8_t* p = (const uint8_t*)message.bytes;
47 |
48 | STMResponse* res = [STMResponse defaultResponse];
49 | res.reqID = ntohl(*(const uint32_t*)p);
50 | p += 4;
51 |
52 | res.status = (STMResponseStatus)*p;
53 | p += 1;
54 |
55 | if (message.length == 5) {
56 | return res;
57 | }
58 |
59 | res.data = [message subdataWithRange:NSMakeRange(5, message.length-5)];
60 |
61 | return res;
62 | }
63 |
64 | -(NSData*)build:(NSData*)body
65 | withHeaders:(NSDictionary*)headers
66 | withReqID:(uint32_t)reqID {
67 | NSInteger length = 0;
68 | NSInteger* lengthp = &length;
69 | BOOL __block failed = NO;
70 | [headers enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key, NSString * _Nonnull obj, BOOL * _Nonnull stop) {
71 | if (key.length > 255 || obj.length > 255) {
72 | *stop = YES;
73 | failed = YES;
74 | }
75 | *lengthp += key.length + obj.length + 1 + 1;
76 | }];
77 |
78 | if (failed == YES) {
79 | return nil;
80 | }
81 |
82 | length += 4 + 1 + ((body == nil)? 0: body.length);
83 |
84 | char* buffer = calloc(length, sizeof(char));
85 | char* __block p = buffer;
86 | *(uint32_t*)p = htonl(reqID);
87 | p += 4;
88 |
89 | [headers enumerateKeysAndObjectsUsingBlock:^(NSString * _Nonnull key
90 | , NSString * _Nonnull obj
91 | , BOOL * _Nonnull stop) {
92 | *p = (char)key.length;
93 | p += 1;
94 | if (NO == [key getCString:p maxLength:(length-(p-buffer)) encoding:NSASCIIStringEncoding]) {
95 | failed = YES;
96 | *stop = YES;
97 | return;
98 | }
99 | p += key.length;
100 |
101 | *p = (char)obj.length;
102 | p += 1;
103 | if (NO == [obj getCString:p maxLength:(length-(p-buffer)) encoding:NSASCIIStringEncoding]) {
104 | failed = YES;
105 | *stop = YES;
106 | return;
107 | }
108 | p += obj.length;
109 | }];
110 |
111 | if (failed == YES) {
112 | return nil;
113 | }
114 |
115 | *p = 0;
116 | p += 1;
117 |
118 | if (body != nil) {
119 | [body getBytes:p length:body.length];
120 | }
121 |
122 | return [NSData dataWithBytesNoCopy:buffer length:length];
123 | }
124 |
125 | -(NSData*)buildFailedMessage:(NSString*)error withReqid:(uint32_t)reqID {
126 | NSData* err = [error dataUsingEncoding:NSUTF8StringEncoding];
127 | char* buffer = calloc(err.length + 4 + 1, sizeof(char));
128 | [err getBytes:buffer+5 length:err.length];
129 | buffer[4] = 1;
130 | *(uint32_t*)buffer = htonl(reqID);
131 |
132 | return [NSData dataWithBytesNoCopy:buffer length:err.length + 4 + 1];
133 | }
134 | @end
135 |
136 |
137 |
138 |
139 |
140 |
141 |
142 |
--------------------------------------------------------------------------------
/stream_module/ngx_stream_request_core_module/ngx_stream_request_variables.h:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Copyright (C) Igor Sysoev
4 | * Copyright (C) Nginx, Inc.
5 | */
6 |
7 |
8 | #ifndef _NGX_STREAM_REQUEST_VARIABLES_H_INCLUDED_
9 | #define _NGX_STREAM_REQUEST_VARIABLES_H_INCLUDED_
10 |
11 |
12 | #include
13 | #include
14 | #include
15 |
16 |
17 | typedef ngx_variable_value_t ngx_stream_request_variable_value_t;
18 |
19 | #define ngx_stream_request_variable(v) { sizeof(v) - 1, 1, 0, 0, 0, (u_char *) v }
20 |
21 | typedef struct ngx_stream_request_variable_s ngx_stream_request_variable_t;
22 |
23 | typedef void (*ngx_stream_request_set_variable_pt) (ngx_stream_request_t *r,
24 | ngx_stream_request_variable_value_t *v, uintptr_t data);
25 | typedef ngx_int_t (*ngx_stream_request_get_variable_pt) (ngx_stream_request_t *r,
26 | ngx_stream_request_variable_value_t *v, uintptr_t data);
27 |
28 |
29 | #define NGX_STREAM_REQUEST_VAR_CHANGEABLE NGX_STREAM_VAR_CHANGEABLE
30 | #define NGX_STREAM_REQUEST_VAR_NOCACHEABLE NGX_STREAM_VAR_NOCACHEABLE
31 | #define NGX_STREAM_REQUEST_VAR_INDEXED NGX_STREAM_VAR_INDEXED
32 | #define NGX_STREAM_REQUEST_VAR_NOHASH NGX_STREAM_VAR_NOHASH
33 | #define NGX_STREAM_REQUEST_VAR_WEAK NGX_STREAM_VAR_WEAK
34 | #define NGX_STREAM_REQUEST_VAR_PREFIX NGX_STREAM_VAR_PREFIX
35 |
36 |
37 | struct ngx_stream_request_variable_s {
38 | ngx_str_t name; /* must be first to build the hash */
39 | ngx_stream_request_set_variable_pt set_handler;
40 | ngx_stream_request_get_variable_pt get_handler;
41 | uintptr_t data;
42 | ngx_uint_t flags;
43 | ngx_uint_t index;
44 | };
45 |
46 |
47 | ngx_stream_request_variable_t *ngx_stream_request_add_variable(ngx_conf_t *cf
48 | , ngx_str_t *name, ngx_uint_t flags);
49 | ngx_int_t ngx_stream_request_get_variable_index(ngx_conf_t *cf, ngx_str_t *name);
50 |
51 | ngx_stream_request_variable_value_t *ngx_stream_request_get_indexed_variable(
52 | ngx_stream_request_t *r, ngx_uint_t index);
53 | ngx_stream_request_variable_value_t *ngx_stream_request_get_flushed_variable(
54 | ngx_stream_request_t *r, ngx_uint_t index);
55 |
56 | ngx_stream_request_variable_value_t *ngx_stream_request_get_variable(
57 | ngx_stream_request_t *r, ngx_str_t *name, ngx_uint_t key);
58 |
59 |
60 | #if (NGX_PCRE)
61 |
62 | typedef struct {
63 | ngx_uint_t capture;
64 | ngx_int_t index;
65 | } ngx_stream_request_regex_variable_t;
66 |
67 |
68 | typedef struct {
69 | ngx_regex_t *regex;
70 | ngx_uint_t ncaptures;
71 | ngx_stream_request_regex_variable_t *variables;
72 | ngx_uint_t nvariables;
73 | ngx_str_t name;
74 | } ngx_stream_request_regex_t;
75 |
76 |
77 | typedef struct {
78 | ngx_stream_request_regex_t *regex;
79 | void *value;
80 | } ngx_stream_request_map_regex_t;
81 |
82 |
83 | ngx_stream_request_regex_t *ngx_stream_request_regex_compile(ngx_conf_t *cf,
84 | ngx_regex_compile_t *rc);
85 | ngx_int_t ngx_stream_request_regex_exec(ngx_stream_request_t *r, ngx_stream_request_regex_t *re,
86 | ngx_str_t *str);
87 |
88 | #endif
89 |
90 |
91 | typedef struct {
92 | ngx_hash_combined_t hash;
93 | #if (NGX_PCRE)
94 | ngx_stream_request_map_regex_t *regex;
95 | ngx_uint_t nregex;
96 | #endif
97 | } ngx_stream_request_map_t;
98 |
99 |
100 | void *ngx_stream_request_map_find(ngx_stream_request_t *r, ngx_stream_request_map_t *map,
101 | ngx_str_t *match);
102 |
103 |
104 | ngx_int_t ngx_stream_request_variables_add_core_vars(ngx_conf_t *cf);
105 | ngx_int_t ngx_stream_request_variables_init_vars(ngx_conf_t *cf);
106 |
107 | extern void ngx_stream_regular_var_name(ngx_str_t*);
108 |
109 | extern ngx_stream_request_variable_value_t ngx_stream_request_variable_null_value;
110 | extern ngx_stream_request_variable_value_t ngx_stream_request_variable_true_value;
111 |
112 |
113 | #endif /* _NGX_STREAM_VARIABLES_H_INCLUDED_ */
114 |
--------------------------------------------------------------------------------
/stream_module/ngx_stream_request_set_module/ngx_stream_request_set_module.c:
--------------------------------------------------------------------------------
1 | //
2 | // ngx_stream_set_module.c
3 | // nginx-1.12
4 | //
5 | // Created by xpwu on 2017/12/17.
6 | // Copyright © 2017年 xpwu. All rights reserved.
7 | //
8 |
9 | #include
10 | #include
11 | #include
12 |
13 | #ifdef this_module
14 | #undef this_module
15 | #endif
16 | #define this_module ngx_stream_request_set_module
17 |
18 | #ifdef core_module
19 | #undef core_module
20 | #endif
21 | #define core_module ngx_stream_request_core_module
22 |
23 | static char * ngx_stream_set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
24 | static ngx_int_t ngx_stream_set_get_variable (ngx_stream_request_t *r,
25 | ngx_stream_variable_value_t *
26 | , uintptr_t data);
27 |
28 | static ngx_command_t ngx_stream_set_commands[] = {
29 |
30 | { ngx_string("rset"),
31 | NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_TAKE2,
32 | ngx_stream_set,
33 | NGX_STREAM_SRV_CONF_OFFSET,
34 | 0,
35 | NULL },
36 |
37 | ngx_null_command
38 | };
39 |
40 |
41 | static ngx_stream_module_t ngx_stream_set_module_ctx = {
42 | NULL, /* preconfiguration */
43 | NULL, /* postconfiguration */
44 |
45 | NULL, /* create main configuration */
46 | NULL, /* init main configuration */
47 |
48 | NULL, /* create server configuration */
49 | NULL /* merge server configuration */
50 | };
51 |
52 | ngx_module_t ngx_stream_request_set_module = {
53 | NGX_MODULE_V1,
54 | &ngx_stream_set_module_ctx, /* module context */
55 | ngx_stream_set_commands, /* module directives */
56 | NGX_STREAM_MODULE, /* module type */
57 | NULL, /* init master */
58 | NULL, /* init module */
59 | NULL, /* init process */
60 | NULL, /* init thread */
61 | NULL, /* exit thread */
62 | NULL, /* exit process */
63 | NULL, /* exit master */
64 | NGX_MODULE_V1_PADDING
65 | };
66 |
67 | static char * ngx_stream_set(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) {
68 | ngx_str_t *value;
69 | ngx_stream_request_compile_complex_value_t ccv;
70 | ngx_stream_request_variable_t *v;
71 |
72 | value = cf->args->elts;
73 |
74 | ngx_memzero(&ccv, sizeof(ngx_stream_request_compile_complex_value_t));
75 |
76 | ccv.cf = cf;
77 | ccv.value = &value[2];
78 | ccv.complex_value = ngx_pcalloc(cf->pool, sizeof(ngx_stream_request_complex_value_t));
79 | if (ngx_stream_request_compile_complex_value(&ccv) != NGX_OK) {
80 | return NGX_CONF_ERROR;
81 | }
82 |
83 | ngx_str_t* var = &value[1];
84 | if (var->data[0] == '$') {
85 | var->data += 1;
86 | var->len -= 1;
87 | }
88 | v = ngx_stream_request_add_variable(cf, var, 0);
89 |
90 | if (v == NULL) {
91 | return NGX_CONF_ERROR;
92 | }
93 | v->data = (uintptr_t)ccv.complex_value;
94 | v->flags = 0;
95 | v->get_handler =ngx_stream_set_get_variable;
96 |
97 | return NGX_CONF_OK;
98 | }
99 |
100 | static ngx_int_t ngx_stream_set_get_variable (ngx_stream_request_t *r,
101 | ngx_stream_variable_value_t *value
102 | , uintptr_t data) {
103 | ngx_stream_request_complex_value_t *complex = (ngx_stream_request_complex_value_t*)data;
104 | ngx_str_t text;
105 |
106 | if (ngx_stream_request_complex_value(r, complex, &text) != NGX_OK) {
107 | return NGX_ERROR;
108 | }
109 |
110 | value->len = (unsigned)text.len;
111 | value->data = text.data;
112 | value->valid = (value->data!=NULL)?1:0;
113 | value->not_found = (value->len==0&&value->data==NULL)?1:0;
114 | value->no_cacheable = (value->len==0||value->data==NULL)?1:0;
115 |
116 | return NGX_OK;
117 | }
118 |
119 |
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | client/js/.idea/workspace.xml
2 |
3 | client/js/.idea/workspace.xml
4 |
5 | client/ts
6 |
7 | *.class
8 |
9 | client/ios/ios-sdk/ios-sdk.xcodeproj/project.pbxproj
10 |
11 | client/ios/ios-sdk/ios-sdk.xcodeproj/project.xcworkspace/contents.xcworkspacedata
12 |
13 | client/ios/ios-sdk/ios-sdk.xcodeproj/project.xcworkspace/xcuserdata/xpwu.xcuserdatad/UserInterfaceState.xcuserstate
14 |
15 | client/ios/ios-sdk/ios-sdk.xcodeproj/xcuserdata/xpwu.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist
16 |
17 | client/ios/ios-sdk/ios-sdk.xcodeproj/xcuserdata/xpwu.xcuserdatad/xcschemes/ios-sdk copy.xcscheme
18 |
19 | client/ios/ios-sdk/ios-sdk.xcodeproj/xcuserdata/xpwu.xcuserdatad/xcschemes/ios-sdk.xcscheme
20 |
21 | client/ios/ios-sdk/ios-sdk.xcodeproj/xcuserdata/xpwu.xcuserdatad/xcschemes/xcschememanagement.plist
22 |
23 | client/java/.idea/compiler.xml
24 |
25 | client/java/.idea/copyright/profiles_settings.xml
26 |
27 | client/java/.idea/description.html
28 |
29 | client/java/.idea/misc.xml
30 |
31 | client/java/.idea/modules.xml
32 |
33 | client/java/.idea/project-template.xml
34 |
35 | client/java/.idea/uiDesigner.xml
36 |
37 | client/java/.idea/workspace.xml
38 |
39 | client/java/stmjava.iml
40 |
41 | client/js/node_modules/
42 |
43 | client/js/node_modules/clone-buffer/index.js
44 |
45 | client/js/node_modules/clone-buffer/LICENSE
46 |
47 | client/js/node_modules/clone-buffer/package.json
48 |
49 | client/js/node_modules/clone-buffer/README.md
50 |
51 | client/js/node_modules/cloneable-readable/.npmignore
52 |
53 | client/js/node_modules/cloneable-readable/.travis.yml
54 |
55 | client/js/node_modules/cloneable-readable/example.js
56 |
57 | client/js/node_modules/cloneable-readable/index.js
58 |
59 | client/js/node_modules/cloneable-readable/LICENSE
60 |
61 | client/java/.idea/artifacts/stm_client.xml
62 |
63 | client/java/.idea/artifacts/stm_test.xml
64 |
65 | client/java/out/test/stmjava/META-INF/MANIFEST.MF
66 |
67 | client/java/out/artifacts/stm_test/stm.test.jar
68 |
69 | client/ios/compile/.deps/
70 |
71 | client/ios/compile/.deps/libclient_arm64_a-STMDefaultContentProtocol.Po
72 |
73 | client/ios/compile/.deps/libclient_arm64_a-STMNet.Po
74 |
75 | client/ios/compile/.deps/libclient_arm64_a-STMResponse.Po
76 |
77 | client/ios/compile/autom4te.cache
78 |
79 | client/ios/compile/aclocal.m4
80 |
81 | client/ios/compile/AUTHORS
82 |
83 | client/ios/compile/ChangeLog
84 |
85 | client/ios/compile/compile
86 |
87 | client/ios/compile/config.log
88 |
89 | client/ios/compile/config.status
90 |
91 | client/ios/compile/configure
92 |
93 | client/ios/compile/COPYING
94 |
95 | client/ios/compile/depcomp
96 |
97 | client/ios/compile/INSTALL
98 |
99 | client/ios/compile/install-sh
100 |
101 | client/ios/compile/*.o
102 |
103 | client/ios/compile/*.a
104 |
105 | client/ios/compile/Makefile
106 |
107 | client/ios/compile/Makefile.in
108 |
109 | client/ios/compile/missing
110 |
111 | client/ios/compile/NEWS
112 |
113 | client/ios/compile/README
114 |
115 | push/php/.idea
116 |
117 | .README.md.swp
118 |
119 | client/ts/.idea
120 |
121 | client/js/test/test.11deyi.html
122 |
123 | client/wxapp/.idea/modules.xml
124 |
125 | client/wxapp/.idea/misc.xml
126 |
127 | client/wxapp/.idea/workspace.xml
128 |
129 | client/wxapp/.idea/wxapp.iml
130 |
131 | .DS_Store
132 |
133 | client/js/test/test.jiba.html
134 |
135 | stream_module.tar
136 |
137 | client/js/.idea/misc.xml
138 |
139 | client/js/.idea/misc.xml
140 |
141 | client/js/.idea/misc.xml
142 |
143 | client/js/.idea/watcherTasks.xml
144 |
145 | client/js/.idea/misc.xml
146 |
147 | client/wxapp/.idea/jsLibraryMappings.xml
148 |
149 | client/wxapp/.idea/watcherTasks.xml
150 |
151 | client/js/.idea/misc.xml
152 |
153 | *.pbxproj
154 |
155 | client/ios/test-stm/test-stm.xcodeproj/project.xcworkspace/contents.xcworkspacedata
156 |
157 | client/ios/test-stm/test-stm.xcodeproj/project.xcworkspace/xcuserdata/xpwu.xcuserdatad/IDEFindNavigatorScopes.plist
158 |
159 | client/ios/test-stm/test-stm.xcodeproj/project.xcworkspace/xcuserdata/xpwu.xcuserdatad/UserInterfaceState.xcuserstate
160 |
161 | client/ios/test-stm/test-stm.xcodeproj/xcuserdata/xpwu.xcuserdatad/xcdebugger/Breakpoints_v2.xcbkptlist
162 |
163 | client/ios/test-stm/test-stm.xcodeproj/xcuserdata/xpwu.xcuserdatad/xcschemes/test-stm.xcscheme
164 | client/js/.idea/vcs.xml
165 | push/php/anywithyou-dev
166 |
--------------------------------------------------------------------------------
/client/java/src/stm/DefaultContentProtocol.java:
--------------------------------------------------------------------------------
1 | package stm;
2 |
3 | import java.io.UnsupportedEncodingException;
4 | import java.util.Arrays;
5 | import java.util.Map;
6 |
7 | /**
8 | *
9 | * Created by xpwu on 2016/11/29.
10 | */
11 |
12 | /**
13 | * content protocol:
14 | * request ---
15 | * reqid | headers | header-end-flag | data
16 | * reqid: 4 bytes, net order;
17 | * headers: < key-len | key | value-len | value > ... ; [optional]
18 | * key-len: 1 byte, key-len = sizeof(key);
19 | * value-len: 1 byte, value-len = sizeof(value);
20 | * header-end-flag: 1 byte, === 0; [optional]
21 | * data: [optional]
22 | *
23 | * response ---
24 | * reqid | status | data
25 | * reqid: 4 bytes, net order;
26 | * status: 1 byte, 0---success, 1---failed
27 | * data: if status==success, data= [optional]
28 | * if status==failed, data=
29 | *
30 | */
31 |
32 | class DefaultContentProtocol implements ContentProtocol {
33 | public Response parse(byte[] content){
34 | Response res = new Response();
35 | res.reqID = 0;
36 | for (int i = 0; i < 4; ++i) {
37 | res.reqID = (res.reqID << 8) + (content[i]&0xff);
38 | }
39 | res.status = content[4] == 0? Response.Status.Success : Response.Status.Failed;
40 | if (content.length <= 5) {
41 | return res;
42 | }
43 | try {
44 | res.data = Arrays.copyOfRange(content, 5, content.length);
45 | } catch (Exception e) {
46 | res.data = null;
47 | }
48 | return res;
49 | }
50 |
51 | public byte[] build(byte[] body, Map headers, long reqID){
52 | int length = 4 + 1;
53 | if (body != null) {
54 | length += body.length;
55 | }
56 | if (headers != null) {
57 | for (Map.Entry entry : headers.entrySet()) {
58 | byte[] key = null;
59 | byte[] value = null;
60 | try {
61 | key = entry.getKey().getBytes("UTF-8");
62 | value = entry.getValue().getBytes("UTF-8");
63 | } catch (UnsupportedEncodingException e) {
64 | return null;
65 | }
66 | if (key.length > 255 || value.length > 255) {
67 | return null;
68 | }
69 | length += 1 + key.length + 1 + value.length;
70 | }
71 | }
72 |
73 | byte[] request = new byte[length];
74 | request[0] = (byte) ((reqID & 0xff000000) >> 24);
75 | request[1] = (byte) ((reqID & 0xff0000) >> 16);
76 | request[2] = (byte) ((reqID & 0xff00) >> 8);
77 | request[3] = (byte) (reqID & 0xff);
78 |
79 | int pos = 4;
80 | if (headers != null) {
81 | for (Map.Entry entry : headers.entrySet()) {
82 | byte[] key = null;
83 | byte[] value = null;
84 | try {
85 | key = entry.getKey().getBytes("UTF-8");
86 | value = entry.getValue().getBytes("UTF-8");
87 | } catch (UnsupportedEncodingException e) {
88 | return null;
89 | }
90 | if (key.length > 255 || value.length > 255) {
91 | return null;
92 | }
93 | request[pos] = (byte) key.length;
94 | pos++;
95 | System.arraycopy(key, 0, request, pos, key.length);
96 | pos += key.length;
97 | request[pos] = (byte) value.length;
98 | pos++;
99 | System.arraycopy(value, 0, request, pos, value.length);
100 | pos += value.length;
101 | }
102 | }
103 | request[pos] = 0; // header-end
104 | pos++;
105 |
106 | if (body != null) {
107 | System.arraycopy(body, 0, request, pos, body.length);
108 | }
109 |
110 | return request;
111 | }
112 |
113 | public byte[] buildFailedMessage(String error, long reqID){
114 | byte[] msg = null;
115 | try {
116 | byte[] err = error.getBytes("UTF-8");
117 | msg = new byte[err.length + 1 + 4];
118 | System.arraycopy(err, 0, msg, 5, err.length);
119 | }catch (UnsupportedEncodingException e) {
120 | msg = new byte[4 + 1];
121 | }
122 | msg[0] = (byte) ((reqID & 0xff000000) >> 24);
123 | msg[1] = (byte) ((reqID & 0xff0000) >> 16);
124 | msg[2] = (byte) ((reqID & 0xff00) >> 8);
125 | msg[3] = (byte) (reqID & 0xff);
126 | msg[4] = 1;
127 |
128 | return msg;
129 | }
130 | }
131 |
--------------------------------------------------------------------------------
/stream_module/ngx_stream_request_core_module/ngx_radix64_tree.c:
--------------------------------------------------------------------------------
1 | //
2 | // ngx_radix64_tree.c
3 | // nginx-1.12
4 | //
5 | // Created by xpwu on 2017/12/24.
6 | // Copyright © 2017年 xpwu. All rights reserved.
7 | //
8 |
9 | #include
10 | #include
11 | #include
12 |
13 |
14 | static ngx_radix_node_t *ngx_radix_alloc(ngx_radix_tree_t *tree);
15 |
16 |
17 | ngx_int_t
18 | ngx_radix64tree_insert(ngx_radix_tree_t *tree, uint64_t key, uint64_t mask,
19 | uintptr_t value)
20 | {
21 | uint64_t bit;
22 | ngx_radix_node_t *node, *next;
23 |
24 | bit = 0x8000000000000000;
25 |
26 | node = tree->root;
27 | next = tree->root;
28 |
29 | while (bit & mask) {
30 | if (key & bit) {
31 | next = node->right;
32 |
33 | } else {
34 | next = node->left;
35 | }
36 |
37 | if (next == NULL) {
38 | break;
39 | }
40 |
41 | bit >>= 1;
42 | node = next;
43 | }
44 |
45 | if (next) {
46 | if (node->value != NGX_RADIX_NO_VALUE) {
47 | return NGX_BUSY;
48 | }
49 |
50 | node->value = value;
51 | return NGX_OK;
52 | }
53 |
54 | while (bit & mask) {
55 | next = ngx_radix_alloc(tree);
56 | if (next == NULL) {
57 | return NGX_ERROR;
58 | }
59 |
60 | next->right = NULL;
61 | next->left = NULL;
62 | next->parent = node;
63 | next->value = NGX_RADIX_NO_VALUE;
64 |
65 | if (key & bit) {
66 | node->right = next;
67 |
68 | } else {
69 | node->left = next;
70 | }
71 |
72 | bit >>= 1;
73 | node = next;
74 | }
75 |
76 | node->value = value;
77 |
78 | return NGX_OK;
79 | }
80 |
81 |
82 | ngx_int_t
83 | ngx_radix64tree_delete(ngx_radix_tree_t *tree, uint64_t key, uint64_t mask)
84 | {
85 | uint64_t bit;
86 | ngx_radix_node_t *node;
87 |
88 | bit = 0x8000000000000000;
89 | node = tree->root;
90 |
91 | while (node && (bit & mask)) {
92 | if (key & bit) {
93 | node = node->right;
94 |
95 | } else {
96 | node = node->left;
97 | }
98 |
99 | bit >>= 1;
100 | }
101 |
102 | if (node == NULL) {
103 | return NGX_ERROR;
104 | }
105 |
106 | if (node->right || node->left) {
107 | if (node->value != NGX_RADIX_NO_VALUE) {
108 | node->value = NGX_RADIX_NO_VALUE;
109 | return NGX_OK;
110 | }
111 |
112 | return NGX_ERROR;
113 | }
114 |
115 | for ( ;; ) {
116 | if (node->parent->right == node) {
117 | node->parent->right = NULL;
118 |
119 | } else {
120 | node->parent->left = NULL;
121 | }
122 |
123 | node->right = tree->free;
124 | tree->free = node;
125 |
126 | node = node->parent;
127 |
128 | if (node->right || node->left) {
129 | break;
130 | }
131 |
132 | if (node->value != NGX_RADIX_NO_VALUE) {
133 | break;
134 | }
135 |
136 | if (node->parent == NULL) {
137 | break;
138 | }
139 | }
140 |
141 | return NGX_OK;
142 | }
143 |
144 |
145 | uintptr_t
146 | ngx_radix64tree_find(ngx_radix_tree_t *tree, uint64_t key)
147 | {
148 | uint64_t bit;
149 | uintptr_t value;
150 | ngx_radix_node_t *node;
151 |
152 | bit = 0x8000000000000000;
153 | value = NGX_RADIX_NO_VALUE;
154 | node = tree->root;
155 |
156 | while (node) {
157 | if (node->value != NGX_RADIX_NO_VALUE) {
158 | value = node->value;
159 | }
160 |
161 | if (key & bit) {
162 | node = node->right;
163 |
164 | } else {
165 | node = node->left;
166 | }
167 |
168 | bit >>= 1;
169 | }
170 |
171 | return value;
172 | }
173 |
174 | static ngx_radix_node_t *
175 | ngx_radix_alloc(ngx_radix_tree_t *tree)
176 | {
177 | ngx_radix_node_t *p;
178 |
179 | if (tree->free) {
180 | p = tree->free;
181 | tree->free = tree->free->right;
182 | return p;
183 | }
184 |
185 | if (tree->size < sizeof(ngx_radix_node_t)) {
186 | tree->start = ngx_pmemalign(tree->pool, ngx_pagesize, ngx_pagesize);
187 | if (tree->start == NULL) {
188 | return NULL;
189 | }
190 |
191 | tree->size = ngx_pagesize;
192 | }
193 |
194 | p = (ngx_radix_node_t *) tree->start;
195 | tree->start += sizeof(ngx_radix_node_t);
196 | tree->size -= sizeof(ngx_radix_node_t);
197 |
198 | return p;
199 | }
200 |
201 |
--------------------------------------------------------------------------------
/stream_module/ngx_stream_request_core_module/ngx_str_str_rbtree.c:
--------------------------------------------------------------------------------
1 | //
2 | // ngx_str_str_rbtree.c
3 | // ngx-1.10.1-xcode
4 | //
5 | // Created by xpwu on 2016/11/18.
6 | // Copyright © 2016年 xpwu. All rights reserved.
7 | //
8 |
9 | #include
10 |
11 | #ifndef ngx_str_str_rbtree_c
12 | #define ngx_str_str_rbtree_c
13 |
14 | typedef struct{
15 | ngx_str_node_t node; // must be first, not be pointer
16 | ngx_str_t value;
17 | } ngx_str_str_rbtree_node_t;
18 |
19 | extern void ngx_str_str_rbtree_init(ngx_str_str_rbtree* tree
20 | , ngx_pool_t* pool, ngx_log_t* log) {
21 | ngx_rbtree_init(&tree->tree, &tree->sentinel
22 | , ngx_str_rbtree_insert_value);
23 | tree->pool = pool;
24 | tree->log = log;
25 | }
26 |
27 | #if (NGX_DEBUG)
28 | static void print_rbtree(ngx_rbtree_node_t* root
29 | , ngx_rbtree_node_t* sentinel
30 | , u_char** buf, u_char* last, ngx_int_t* end) {
31 | if (root == sentinel) {
32 | return;
33 | }
34 |
35 | if (*end == 1) {
36 | return;
37 | }
38 |
39 | print_rbtree(root->left, sentinel, buf, last, end);
40 |
41 | ngx_str_str_rbtree_node_t* node = (ngx_str_str_rbtree_node_t*)root;
42 | if (*buf + node->node.str.len + node->value.len + 4 > last) {
43 | *buf = ngx_cpymem(*buf, ";...", 4);
44 | *end = 1;
45 | } else {
46 | *buf = ngx_cpymem(*buf, node->node.str.data, node->node.str.len);
47 | *buf = ngx_cpymem(*buf, ": ", 2);
48 | *buf = ngx_cpymem(*buf, node->value.data, node->value.len);
49 | *buf = ngx_cpymem(*buf, "; ", 2);
50 | }
51 |
52 | print_rbtree(root->right, sentinel, buf, last, end);
53 | }
54 | #endif
55 |
56 | extern ngx_str_t ngx_str_str_rbtree_get_value(ngx_str_str_rbtree* tree
57 | , ngx_str_t key) {
58 | #if (NGX_DEBUG)
59 | ngx_log_t* log = tree->log;
60 | u_char allVar[1024];
61 | u_char* last = allVar + 1024;
62 | u_char* buf = allVar;
63 | ngx_int_t end = 0;
64 | print_rbtree(tree->tree.root, tree->tree.sentinel, &buf, last, &end);
65 | ngx_log_debug3(NGX_LOG_DEBUG_STREAM, log, 0
66 | , "ngx str_str_rbtree<%p> all variable is {%*s}"
67 | , tree, buf-allVar, allVar);
68 | #endif
69 |
70 | ngx_str_t res = ngx_null_string;
71 |
72 | ngx_str_node_t* node = ngx_str_rbtree_lookup(&tree->tree, &key, 0);
73 | if (node == NULL) {
74 | ngx_log_debug2(NGX_LOG_DEBUG_STREAM, tree->log, 0
75 | , "ngx str_str_rbtree<%p> get key(%V) is null"
76 | , tree, &key);
77 | return res;
78 | }
79 |
80 | ngx_str_str_rbtree_node_t* vnode = (ngx_str_str_rbtree_node_t*)node;
81 | ngx_log_debug3(NGX_LOG_DEBUG_STREAM, tree->log, 0
82 | , "ngx str_str_rbtree<%p> get key(%V) is (%V)"
83 | , tree, &key, &vnode->value);
84 | return vnode->value;
85 | }
86 |
87 | extern void ngx_str_str_rbtree_set_value(ngx_str_str_rbtree* tree
88 | , ngx_str_t key
89 | , ngx_str_t value
90 | , ngx_int_t force_rewrite) {
91 | ngx_str_str_rbtree_node_t* vnode;
92 |
93 | ngx_str_node_t* node = ngx_str_rbtree_lookup(&tree->tree, &key, 0);
94 |
95 | if (node != NULL && force_rewrite == 0) {
96 | #if (NGX_DEBUG)
97 | ngx_str_str_rbtree_node_t* vnode = (ngx_str_str_rbtree_node_t*)node;
98 | ngx_log_debug3(NGX_LOG_DEBUG_STREAM, tree->log, 0
99 | , "ngx str_str_rbtree<%p> key(%V) has value (%V) yet"
100 | ,tree, &key, &vnode->value);
101 | #endif
102 | return;
103 | }
104 |
105 | if (node != NULL) {
106 | vnode = (ngx_str_str_rbtree_node_t*)node;
107 | if (vnode->value.len >= value.len) {
108 | ngx_memcpy(vnode->value.data, value.data, value.len);
109 | } else {
110 | ngx_pfree(tree->pool, vnode->value.data);
111 | vnode->value.data = ngx_pcalloc(tree->pool, value.len);
112 | ngx_memcpy(vnode->value.data, value.data, value.len);
113 | }
114 | vnode->value.len = value.len;
115 | return;
116 | }
117 |
118 | vnode = ngx_pcalloc(tree->pool, sizeof(ngx_str_str_rbtree_node_t));
119 | /**
120 | * set by ngx_pcalloc:
121 | * vnode->node.node.key = 0;
122 | */
123 | vnode->value.data = ngx_pcalloc(tree->pool, value.len);
124 | ngx_memcpy(vnode->value.data, value.data, value.len);
125 | vnode->value.len = value.len;
126 |
127 | vnode->node.str.len = key.len;
128 | vnode->node.str.data = ngx_pcalloc(tree->pool, key.len);
129 | ngx_memcpy(vnode->node.str.data, key.data, key.len);
130 |
131 | ngx_rbtree_insert(&tree->tree, (ngx_rbtree_node_t*)vnode);
132 | }
133 |
134 | #endif //~ngx_str_str_rbtree_c
135 |
--------------------------------------------------------------------------------
/stream_module/ngx_stream_request_core_module/ngx_stream_request_script.h:
--------------------------------------------------------------------------------
1 |
2 | /*
3 | * Copyright (C) Igor Sysoev
4 | * Copyright (C) Nginx, Inc.
5 | */
6 |
7 |
8 | #ifndef _NGX_STREAM_REQUEST_SCRIPT_H_INCLUDED_
9 | #define _NGX_STREAM_REQUEST_SCRIPT_H_INCLUDED_
10 |
11 |
12 | #include
13 | #include
14 | #include
15 |
16 |
17 | typedef struct {
18 | u_char *ip;
19 | u_char *pos;
20 | ngx_stream_request_variable_value_t *sp;
21 |
22 | ngx_str_t buf;
23 | ngx_str_t line;
24 |
25 | unsigned flushed:1;
26 | unsigned skip:1;
27 |
28 | ngx_stream_request_t *request;
29 | } ngx_stream_request_script_engine_t;
30 |
31 |
32 | //typedef struct {
33 | // ngx_conf_t *cf;
34 | // ngx_str_t *source;
35 | //
36 | // ngx_array_t **flushes;
37 | // ngx_array_t **lengths;
38 | // ngx_array_t **values;
39 | //
40 | // ngx_uint_t variables;
41 | // ngx_uint_t ncaptures;
42 | // ngx_uint_t size;
43 | //
44 | // void *main;
45 | //
46 | // unsigned complete_lengths:1;
47 | // unsigned complete_values:1;
48 | // unsigned zero:1;
49 | // unsigned conf_prefix:1;
50 | // unsigned root_prefix:1;
51 | //} ngx_stream_script_compile_t;
52 |
53 | typedef ngx_stream_script_compile_t ngx_stream_request_script_compile_t;
54 |
55 |
56 | //typedef struct {
57 | // ngx_str_t value;
58 | // ngx_uint_t *flushes;
59 | // void *lengths;
60 | // void *values;
61 | //} ngx_stream_complex_value_t;
62 |
63 | typedef ngx_stream_complex_value_t ngx_stream_request_complex_value_t;
64 |
65 |
66 | typedef struct {
67 | ngx_conf_t *cf;
68 | ngx_str_t *value;
69 | ngx_stream_request_complex_value_t *complex_value;
70 |
71 | unsigned zero:1;
72 | unsigned conf_prefix:1;
73 | unsigned root_prefix:1;
74 | } ngx_stream_request_compile_complex_value_t;
75 |
76 |
77 | typedef void (*ngx_stream_request_script_code_pt)
78 | (ngx_stream_request_script_engine_t *e);
79 | typedef size_t (*ngx_stream_request_script_len_code_pt) (ngx_stream_request_script_engine_t *e);
80 |
81 |
82 | typedef struct {
83 | ngx_stream_request_script_code_pt code;
84 | uintptr_t len;
85 | } ngx_stream_request_script_copy_code_t;
86 |
87 |
88 | typedef struct {
89 | ngx_stream_request_script_code_pt code;
90 | uintptr_t index;
91 | } ngx_stream_request_script_var_code_t;
92 |
93 |
94 | typedef struct {
95 | ngx_stream_request_script_code_pt code;
96 | uintptr_t n;
97 | } ngx_stream_request_script_copy_capture_code_t;
98 |
99 |
100 | typedef struct {
101 | ngx_stream_request_script_code_pt code;
102 | uintptr_t conf_prefix;
103 | } ngx_stream_request_script_full_name_code_t;
104 |
105 |
106 | void ngx_stream_request_script_flush_complex_value(ngx_stream_request_t *r,
107 | ngx_stream_request_complex_value_t *val);
108 | ngx_int_t ngx_stream_request_complex_value(ngx_stream_request_t *r,
109 | ngx_stream_request_complex_value_t *val, ngx_str_t *value);
110 | ngx_int_t ngx_stream_request_compile_complex_value(
111 | ngx_stream_request_compile_complex_value_t *ccv);
112 | char *ngx_stream_request_set_complex_value_slot(ngx_conf_t *cf
113 | , ngx_command_t *cmd,
114 | void *conf);
115 |
116 |
117 | ngx_uint_t ngx_stream_request_script_variables_count(ngx_str_t *value);
118 | ngx_int_t ngx_stream_request_script_compile(
119 | ngx_stream_request_script_compile_t *sc);
120 | u_char *ngx_stream_request_script_run(ngx_stream_request_t *r
121 | , ngx_str_t *value,
122 | void *code_lengths, size_t reserved, void *code_values);
123 | void ngx_stream_request_script_flush_no_cacheable_variables(
124 | ngx_stream_request_t *r,
125 | ngx_array_t *indices);
126 |
127 | void *ngx_stream_request_script_add_code(ngx_array_t *codes, size_t size, void *code);
128 |
129 | size_t ngx_stream_request_script_copy_len_code(ngx_stream_request_script_engine_t *e);
130 | void ngx_stream_request_script_copy_code(ngx_stream_request_script_engine_t *e);
131 | size_t ngx_stream_request_script_copy_var_len_code(ngx_stream_request_script_engine_t *e);
132 | void ngx_stream_request_script_copy_var_code(ngx_stream_request_script_engine_t *e);
133 | size_t ngx_stream_request_script_copy_capture_len_code(ngx_stream_request_script_engine_t *e);
134 | void ngx_stream_request_script_copy_capture_code(ngx_stream_request_script_engine_t *e);
135 |
136 | #endif /* _NGX_STREAM_SCRIPT_H_INCLUDED_ */
137 |
--------------------------------------------------------------------------------
/stream_module/ngx_stream_request_push_data_module/ngx_stream_request_push_data_module.c:
--------------------------------------------------------------------------------
1 | //
2 | // ngx_stream_request_push_data_module.c
3 | // nginx-1.12
4 | //
5 | // Created by xpwu on 2017/12/24.
6 | // Copyright © 2017年 xpwu. All rights reserved.
7 | //
8 |
9 | #include
10 | #include
11 | #include
12 |
13 | #include
14 |
15 | #ifdef this_module
16 | #undef this_module
17 | #endif
18 | #define this_module ngx_stream_request_push_data_module
19 |
20 | #ifdef core_module
21 | #undef core_module
22 | #endif
23 | #define core_module ngx_stream_request_core_module
24 |
25 | typedef struct{
26 | ngx_uint_t sub_protocol;
27 | ngx_int_t handler_index;
28 | } ngx_stream_request_push_data_svr_conf_t;
29 |
30 | static void *ngx_stream_request_push_data_create_srv_conf(ngx_conf_t *cf);
31 | static char *ngx_stream_request_push_data_merge_srv_conf(ngx_conf_t *cf
32 | , void *parent, void *child);
33 |
34 | static char *push_data_conf(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
35 |
36 | static ngx_command_t ngx_stream_push_data_commands[] = {
37 |
38 | { ngx_string("push_data_subprotocol"),
39 | NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_NOARGS|NGX_CONF_TAKE1,
40 | push_data_conf,
41 | NGX_STREAM_SRV_CONF_OFFSET,
42 | 0,
43 | NULL },
44 |
45 | ngx_null_command
46 | };
47 |
48 | static ngx_stream_module_t ngx_stream_push_data_module_ctx = {
49 | NULL,
50 | NULL, /* postconfiguration */
51 |
52 | NULL, /* create main configuration */
53 | NULL, /* init main configuration */
54 |
55 | ngx_stream_request_push_data_create_srv_conf, /* create server configuration */
56 | ngx_stream_request_push_data_merge_srv_conf /* merge server configuration */
57 | };
58 |
59 | ngx_module_t ngx_stream_request_push_data_module = {
60 | NGX_MODULE_V1,
61 | &ngx_stream_push_data_module_ctx, /* module context */
62 | ngx_stream_push_data_commands, /* module directives */
63 | NGX_STREAM_MODULE, /* module type */
64 | NULL, /* init master */
65 | NULL, /* init module */
66 | NULL, /* init process */
67 | NULL, /* init thread */
68 | NULL, /* exit thread */
69 | NULL, /* exit process */
70 | NULL, /* exit master */
71 | NGX_MODULE_V1_PADDING
72 | };
73 |
74 | static void *ngx_stream_request_push_data_create_srv_conf(ngx_conf_t *cf) {
75 | ngx_stream_request_push_data_svr_conf_t* pscf;
76 | pscf = ngx_palloc(cf->pool, sizeof(ngx_stream_request_push_data_svr_conf_t));
77 |
78 | pscf->sub_protocol = NGX_CONF_UNSET_UINT;
79 |
80 | return pscf;
81 | }
82 |
83 | static char *ngx_stream_request_push_data_merge_srv_conf(ngx_conf_t *cf
84 | , void *parent, void *child) {
85 | ngx_stream_request_push_data_svr_conf_t* conf = child;
86 | ngx_stream_request_push_data_svr_conf_t* prev = parent;
87 |
88 | ngx_conf_merge_uint_value(conf->sub_protocol
89 | , prev->sub_protocol, NGX_CONF_UNSET_UINT);
90 |
91 | return NGX_CONF_OK;
92 | }
93 |
94 | static ngx_int_t handle_request(ngx_stream_request_t*);
95 | static ngx_int_t build_response(ngx_stream_request_t*);
96 |
97 | static char *push_data_conf(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) {
98 |
99 | ngx_stream_request_push_data_svr_conf_t* pscf = conf;
100 | ngx_str_t* value = cf->args->elts;
101 |
102 | ngx_stream_request_handler_t* handler;
103 |
104 | handler = ngx_stream_request_add_handler(cf);
105 | pscf->handler_index = handler->index;
106 | handler->name = "push data";
107 | if (cf->args->nelts == 2) {
108 | handler->subprotocol_flag = ngx_atoi(value[1].data, value[1].len);
109 | } else {
110 | handler->subprotocol_flag = 0; // default subprotocol: 0
111 | }
112 | pscf->sub_protocol = handler->subprotocol_flag;
113 | handler->build_response = build_response;
114 | handler->handle_request = handle_request;
115 |
116 | return NGX_CONF_OK;
117 | }
118 |
119 | static ngx_int_t
120 | push_data_dist_hander(ngx_stream_request_t*);
121 |
122 | typedef struct{
123 | ngx_int_t done;
124 | } request_src_ctx_t;
125 |
126 | static ngx_int_t handle_request(ngx_stream_request_t* r) {
127 | request_src_ctx_t* ctx = ngx_stream_request_get_module_ctx(r, this_module);
128 | if (ctx == NULL) {
129 | ctx = ngx_pcalloc(r->pool, sizeof(request_src_ctx_t));
130 | ngx_stream_request_set_ctx(r, ctx, this_module);
131 | }
132 | if (ctx->done == 1) {
133 | return NGX_OK;
134 | }
135 |
136 | return ngx_stream_request_push_to_dist_process(r, push_data_dist_hander);
137 | }
138 |
139 | static ngx_int_t build_response(ngx_stream_request_t* r) {
140 | r->data->buf->last = r->data->buf->pos;
141 | return NGX_OK;
142 | }
143 |
144 | ngx_int_t
145 | push_data_dist_hander(ngx_stream_request_t* r) {
146 | ngx_stream_handle_request_from(r, -1, 1);
147 | return NGX_OK;
148 | }
149 |
150 |
--------------------------------------------------------------------------------
/client/js/dest/stm.client.min.js:
--------------------------------------------------------------------------------
1 | !function(t){"use strict";function e(){this.reqID=0,this.state=r.Success,this.data=null}var n=t.stm=t.stm||{},r={Success:0,Failed:1};n.Response=e,n.Response.State=r}(this),function(t){"use strict";var e=t.stm=t.stm||{};e.ContentProtocol={onOpen:function(t){t()},onClose:function(){},parse:function(t){return new e.Response},build:function(t,e,n){return new ArrayBuffer(2)},buildFailedMessage:function(t,e){return new ArrayBuffer(2)},extend:function(t){if(t.__proto__)t.__proto__=this;else{for(var e in this)this.hasOwnProperty(e)&&!t.hasOwnProperty(e)&&(t[e]=this[e]);this.hasOwnProperty("toString")&&!t.hasOwnProperty("toString")&&(t.toString=this.toString)}return t.$parent=this,t}}}(this),function(t){"use strict";var e=t.stm=t.stm||{};e.DefaultContentProtocol={parse:function(t){var n=new e.Response,r=new DataView(t);return n.reqID=r.getUint32(0),n.state=0==r.getUint8(4)?e.Response.State.Success:e.Response.State.Failed,n.data=t.slice(5),n},build:function(t,e,n){if(t=t||"","string"!=typeof t&&!(t instanceof ArrayBuffer))return"body type is error, must be string or ArrayBuffer";if(e=e||{},"object"!=typeof e)return"headers must be a object type, for example {uri: '/location'}";var r=0;for(var o in e)if(e.hasOwnProperty(o)){if("string"!=typeof o||"string"!=typeof e[o])return"headers' key or property must be string";if(o.length>255)return"length of headers' key <"+o+"> more than 255";if(e[o].length>255)return"length of headers' object <"+e[o]+"> more than 255";0!=o.length&&0!=e[o].length&&(r+=2+o.length+e[o].length)}t=new StringView(t);var i=new ArrayBuffer(4+t.rawData.byteLength+1+r);new DataView(i).setUint32(0,n);var s=4;for(o in e)e.hasOwnProperty(o)&&(new DataView(i).setUint8(s,o.length),s++,new Uint8Array(i).set(new StringView(o).rawData,s),s+=o.length,new DataView(i).setUint8(s,e[o].length),s++,new Uint8Array(i).set(new StringView(e[o]).rawData,s),s+=e[o].length);return new DataView(i).setUint8(s,0),s++,new Uint8Array(i).set(t.rawData,s),i},buildFailedMessage:function(t,n){t=new StringView(t);var r=new ArrayBuffer(4+t.rawData.byteLength+1);return new DataView(r).setUint32(0,n),new DataView(r).setUint8(4,e.Response.State.Failed),new Uint8Array(r).set(t.rawData,5),r}}}(this),function(t){"use strict";function e(t,e,n,r,o,i){this.body=t||"",this.headers=n||{},this.onSuccess=e||function(t){},this.onFailed=r||function(t){},this.onComplete=o||function(){},this.reqID=i}function n(){function t(t){t.net_=null,t.netArgs_="",t.requests_=Object.create(null),t.protocol_=l.ContentProtocol.extend(l.DefaultContentProtocol),t.reqID_=s,t.onConnectionSuc_=function(){},t.onConnectionFaild_=function(t){},t.normalOnMessage_=function(t){},t.connectTimeout_=30}t(this),this.onPush=function(t){},this.onPushJson=null}function r(t){return new i(t)}function o(t){setTimeout(t,0)}function i(t){this.client_=t}if("function"!=typeof StringView)return void console.error("can not find StringView. this error maybe cause 'stm.Client is not a constructor'. you can find in https://developer.mozilla.org/en-US/Add-ons/Code_snippets/StringView or https://github.com/madmurphy/stringview.js");var s=200,a=1,u=n.prototype;u.setConnectArgs=function(t,e,n){this.netArgs_=t,this.onConnectionFaild_=n||function(t){},this.onConnectionSuc_=e||function(){}},u.setConfig=function(t){this.connectTimeout_=t},u.addJsonRequest=function(t,e,n,r,o){var i=null==e?null:function(t){e(JSON.parse(new StringView(t).toString()))};this.addRequest(JSON.stringify(null===t?null:t),i,n,r,o)},u.addRequest=function(t,n,o,i,s){if(null==this.netArgs_)return"function"==typeof s&&s(),void("function"==typeof i&&i("net args not set"));var a=r(this).getReqID();return this.requests_[a.toString()]=new e(t,n,o,i,s,a),null!=this.net_&&this.net_.readyState==WebSocket.OPEN?void r(this).sendRequest(this.requests_[a.toString()]):void(null!=this.net_&&this.net_.readyState==WebSocket.CONNECTING||r(this).connect())};var c=i.prototype;c.getReqID=function(){return this.client_.reqID_++,this.client_.reqID_"):(r.onComplete(),n.state!=l.Response.State.Success?null===n.data||void 0===n.data?r.onFailed("may be server error, but server has closed the error log"):r.onFailed(new StringView(n.data).toString()):r.onSuccess(n.data),void delete t.requests_[n.reqID.toString()])},this.client_.net_=new WebSocket(this.client_.netArgs_),t.net_.haserror=!1,t.net_.binaryType="arraybuffer",t.net_.onmessage=function(e){t.normalOnMessage_(e.data)};var e=setTimeout(function(){t.net_.timeout()},1e3*t.connectTimeout_),n=this;t.net_.onopen=function(r){null!=e&&(clearTimeout(e),e=null),n.sendAllRequest(),t.protocol_.onOpen(t.onConnectionSuc_)},t.net_.onclose=function(r){null!=e&&(clearTimeout(e),e=null),t.net_.close(1e3),t.protocol_.onClose(),t.net_.haserror||(t.net_.haserror=!1,n.netError("connection closed by peer or connection error"))},t.net_.onerror=function(r){t.net_.haserror=!0,null!=e&&(clearTimeout(e),e=null),n.netError("connect error---"+JSON.stringify(r))},t.net_.timeout=function(r){e=null,this.onopen=function(t){},this.onclose=function(t){},this.onerror=function(t){},this.onmessage=function(t){},t.net_=null,n.netError("connect timeout")}},c.sendAllRequest=function(){var t=this.client_;for(var e in t.requests_)this.sendRequest(t.requests_[e])},c.errorAllRequest=function(t){var e=this.client_;for(var n in e.requests_)!function(n){o(function(){e.normalOnMessage_(e.protocol_.buildFailedMessage(t,n))})}(Number(n))},c.netError=function(t){var e=this.client_;this.errorAllRequest(t),e.onConnectionFaild_(t)};var l=t.stm=t.stm||{};l.Client=n}(this);
--------------------------------------------------------------------------------
/stream_module/ngx_stream_request_push_close_session_module/ngx_stream_request_push_close_session_module.c:
--------------------------------------------------------------------------------
1 | //
2 | // ngx_stream_request_push_data_module.c
3 | // nginx-1.12
4 | //
5 | // Created by xpwu on 2017/12/24.
6 | // Copyright © 2017年 xpwu. All rights reserved.
7 | //
8 |
9 | #include
10 | #include
11 | #include
12 |
13 | #include
14 |
15 | #ifdef this_module
16 | #undef this_module
17 | #endif
18 | #define this_module ngx_stream_request_push_close_session_module
19 |
20 | #ifdef core_module
21 | #undef core_module
22 | #endif
23 | #define core_module ngx_stream_request_core_module
24 |
25 | typedef struct{
26 | ngx_uint_t sub_protocol;
27 | ngx_int_t handler_index;
28 | } ngx_stream_request_push_close_session_svr_conf_t;
29 |
30 | static void *ngx_stream_request_push_close_session_create_srv_conf(ngx_conf_t *cf);
31 | static char *ngx_stream_request_push_close_session_merge_srv_conf(ngx_conf_t *cf
32 | , void *parent, void *child);
33 |
34 | static char *push_close_session_conf(ngx_conf_t *cf
35 | , ngx_command_t *cmd, void *conf);
36 |
37 | static ngx_command_t ngx_stream_push_close_session_commands[] = {
38 |
39 | { ngx_string("push_close_session_subprotocol"),
40 | NGX_STREAM_MAIN_CONF|NGX_STREAM_SRV_CONF|NGX_CONF_NOARGS|NGX_CONF_TAKE1,
41 | push_close_session_conf,
42 | NGX_STREAM_SRV_CONF_OFFSET,
43 | 0,
44 | NULL },
45 |
46 | ngx_null_command
47 | };
48 |
49 | static ngx_stream_module_t ngx_stream_push_close_session_module_ctx = {
50 | NULL,
51 | NULL, /* postconfiguration */
52 |
53 | NULL, /* create main configuration */
54 | NULL, /* init main configuration */
55 |
56 | ngx_stream_request_push_close_session_create_srv_conf, /* create server configuration */
57 | ngx_stream_request_push_close_session_merge_srv_conf /* merge server configuration */
58 | };
59 |
60 | ngx_module_t ngx_stream_request_push_close_session_module = {
61 | NGX_MODULE_V1,
62 | &ngx_stream_push_close_session_module_ctx, /* module context */
63 | ngx_stream_push_close_session_commands, /* module directives */
64 | NGX_STREAM_MODULE, /* module type */
65 | NULL, /* init master */
66 | NULL, /* init module */
67 | NULL, /* init process */
68 | NULL, /* init thread */
69 | NULL, /* exit thread */
70 | NULL, /* exit process */
71 | NULL, /* exit master */
72 | NGX_MODULE_V1_PADDING
73 | };
74 |
75 | static void *ngx_stream_request_push_close_session_create_srv_conf(ngx_conf_t *cf) {
76 | ngx_stream_request_push_close_session_svr_conf_t* pscf;
77 | pscf = ngx_palloc(cf->pool, sizeof(ngx_stream_request_push_close_session_svr_conf_t));
78 |
79 | pscf->sub_protocol = NGX_CONF_UNSET_UINT;
80 |
81 | return pscf;
82 | }
83 |
84 | static char *ngx_stream_request_push_close_session_merge_srv_conf(ngx_conf_t *cf
85 | , void *parent, void *child) {
86 | ngx_stream_request_push_close_session_svr_conf_t* conf = child;
87 | ngx_stream_request_push_close_session_svr_conf_t* prev = parent;
88 |
89 | ngx_conf_merge_uint_value(conf->sub_protocol
90 | , prev->sub_protocol, NGX_CONF_UNSET_UINT);
91 |
92 | return NGX_CONF_OK;
93 | }
94 |
95 | static ngx_int_t handle_request(ngx_stream_request_t*);
96 | static ngx_int_t build_response(ngx_stream_request_t*);
97 |
98 | static char *push_close_session_conf(ngx_conf_t *cf
99 | , ngx_command_t *cmd, void *conf) {
100 |
101 | ngx_stream_request_push_close_session_svr_conf_t* pscf = conf;
102 | ngx_str_t* value = cf->args->elts;
103 |
104 | ngx_stream_request_handler_t* handler;
105 |
106 | handler = ngx_stream_request_add_handler(cf);
107 | pscf->handler_index = handler->index;
108 | handler->name = "push close session";
109 | if (cf->args->nelts == 2) {
110 | handler->subprotocol_flag = ngx_atoi(value[1].data, value[1].len);
111 | } else {
112 | handler->subprotocol_flag = 1; // default subprotocol: 1
113 | }
114 | pscf->sub_protocol = handler->subprotocol_flag;
115 | handler->build_response = build_response;
116 | handler->handle_request = handle_request;
117 |
118 | return NGX_CONF_OK;
119 | }
120 |
121 | static ngx_int_t
122 | push_close_session_dist_hander(ngx_stream_request_t*);
123 |
124 | typedef struct{
125 | ngx_int_t done;
126 | } request_src_ctx_t;
127 |
128 | static ngx_int_t handle_request(ngx_stream_request_t* r) {
129 | request_src_ctx_t* ctx = ngx_stream_request_get_module_ctx(r, this_module);
130 | if (ctx == NULL) {
131 | ctx = ngx_pcalloc(r->pool, sizeof(request_src_ctx_t));
132 | ngx_stream_request_set_ctx(r, ctx, this_module);
133 | }
134 | if (ctx->done == 1) {
135 | return NGX_OK;
136 | }
137 |
138 | ctx->done = 1;
139 |
140 | return ngx_stream_request_push_to_dist_process(r
141 | , push_close_session_dist_hander);
142 | }
143 |
144 | static ngx_int_t build_response(ngx_stream_request_t* r) {
145 | r->data->buf->last = r->data->buf->pos;
146 | return NGX_OK;
147 | }
148 |
149 | static void finalize_async(ngx_event_t* event) {
150 | ngx_stream_session_t* s = event->data;
151 | ngx_stream_finalize_session_r_level(s, "push close session", NGX_LOG_NOTICE);
152 | }
153 |
154 | ngx_int_t
155 | push_close_session_dist_hander(ngx_stream_request_t* r) {
156 | r->data->buf->last = r->data->buf->pos;
157 | r->data->next = NULL;
158 |
159 | ngx_event_t* e = ngx_pcalloc(r->pool, sizeof(ngx_event_t));
160 | e->handler = finalize_async;
161 | e->data = r->session;
162 | e->log = r->session->connection->log;
163 |
164 | ngx_post_event(e, &ngx_posted_events);
165 |
166 | return NGX_OK;
167 | }
168 |
169 |
--------------------------------------------------------------------------------
/client/ios/test-stm/test-stm/ViewController.mm:
--------------------------------------------------------------------------------
1 | //
2 | // ViewController.m
3 | // test-stm
4 | //
5 | // Created by xpwu on 2016/12/13.
6 | // Copyright © 2016年 xpwuxpwu. All rights reserved.
7 | //
8 |
9 | #import "ViewController.h"
10 | //#import "../../out/STMClient.h"
11 | #import "../../STMClient.h"
12 |
13 | @interface ViewController () {
14 | STMClient* client;
15 | STMClient* client2;
16 | }
17 |
18 | @end
19 |
20 | @implementation ViewController
21 |
22 | - (void)viewDidLoad {
23 | [super viewDidLoad];
24 | // Do any additional setup after loading the view, typically from a nib.
25 | client = [[STMClient alloc]init];
26 | client2 = [[STMClient alloc]init];
27 |
28 | [client setConnectHost:@"127.0.0.1" port:8000
29 | onSuccess:^{
30 | NSLog(@"client1 connect successful");
31 | }
32 | onFailed:^(NSString * error) {
33 | NSLog(@"client1 %@", error);
34 | }];
35 | [client2 setConnectHost:@"127.0.0.1" port:8002
36 | onSuccess:^{
37 | NSLog(@"client2 connect successful");
38 | }
39 | onFailed:^(NSString * error) {
40 | NSLog(@"client2 %@", error);
41 | }];
42 |
43 | client.onpush = ^(NSData* data) {
44 | NSLog(@"[client1 push]---%@", [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);
45 | };
46 |
47 | client2.onpush = ^(NSData* data) {
48 | NSLog(@"[client2 push]---%@"
49 | , [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);
50 | };
51 |
52 | [client addRequestBody:[@"flajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfjsdklflaflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklf" dataUsingEncoding:NSUTF8StringEncoding] headers:@{@"api": @"/api/ServerInfo"} onSuccess:^(NSData * data) {
53 | NSLog(@"client1 success, %@", [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);
54 | } onFailed:^(NSString * str) {
55 | NSLog(@"client1 %@", str);
56 | } onComplete:^{
57 | NSLog(@"client1 complete");
58 | }];
59 |
60 | [client addRequestBody:[@"flajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfjsdklflaflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklf" dataUsingEncoding:NSUTF8StringEncoding] headers:@{@"api": @"/api/php/info"} onSuccess:^(NSData * data) {
61 | NSLog(@"client1 success, %@", [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);
62 | } onFailed:^(NSString * str) {
63 | NSLog(@"client1 %@", str);
64 | } onComplete:^{
65 | NSLog(@"client1 complete");
66 | }];
67 |
68 | [client2 addRequestBody:[@"client2" dataUsingEncoding:NSUTF8StringEncoding] headers:@{@"api": @"api/php/info"} onSuccess:^(NSData * data) {
69 | NSLog(@"client2 success, %@", [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);
70 | } onFailed:^(NSString * str) {
71 | NSLog(@"client2 %@", str);
72 | } onComplete:^{
73 | NSLog(@"client2 complete");
74 | }];
75 | }
76 |
77 | - (void)didReceiveMemoryWarning {
78 | [super didReceiveMemoryWarning];
79 | // Dispose of any resources that can be recreated.
80 | }
81 |
82 | -(IBAction)selector:(id)sender {
83 | [client addRequestBody:[@"flajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfjsdklflaflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklfjsdklflajsfjklsdfjklasdklf" dataUsingEncoding:NSUTF8StringEncoding] headers:@{@"api": @"/api/php/info"} onSuccess:^(NSData * data) {
84 | NSLog(@"client1 success, %@", [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);
85 | } onFailed:^(NSString * str) {
86 | NSLog(@"client1 %@", str);
87 | } onComplete:^{
88 | NSLog(@"client1 complete");
89 | }];
90 |
91 |
92 | [client2 addRequestBody:[@"client2" dataUsingEncoding:NSUTF8StringEncoding] headers:@{@"api": @"api/php/info"} onSuccess:^(NSData * data) {
93 | NSLog(@"client2 success, %@", [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);
94 | } onFailed:^(NSString * str) {
95 | NSLog(@"client2 %@", str);
96 | } onComplete:^{
97 | NSLog(@"client2 complete");
98 | }];
99 |
100 | }
101 |
102 | @end
103 |
--------------------------------------------------------------------------------
/stream_module/ngx_stream_request_core_module/ngx_stream_request.h:
--------------------------------------------------------------------------------
1 | //
2 | // ngx_stream_request.h
3 | // nginx-1.12
4 | //
5 | // Created by xpwu on 2017/12/16.
6 | // Copyright © 2017年 xpwu. All rights reserved.
7 | //
8 |
9 | #ifndef ngx_stream_request_h
10 | #define ngx_stream_request_h
11 |
12 | #include
13 | #include
14 | #include
15 |
16 | #include
17 | #include
18 |
19 | #define NGX_HANDLER_STOP NGX_DECLINED
20 |
21 | typedef struct ngx_stream_request_s ngx_stream_request_t;
22 | typedef struct ngx_stream_request_upstream_s ngx_stream_request_upstream_t;
23 | typedef struct ngx_stream_request_core_srv_conf_s ngx_stream_request_core_srv_conf_t;
24 | typedef struct ngx_stream_request_handler_s ngx_stream_request_handler_t;
25 | typedef struct ngx_stream_request_protocol_s ngx_stream_request_protocol_t;
26 |
27 | #include
28 | #include
29 | #include
30 |
31 | typedef struct ngx_stream_request_cleanup_s ngx_stream_request_cleanup_t;
32 | typedef struct ngx_stream_cleanup_s ngx_stream_cleanup_t;
33 | typedef void (*ngx_stream_cleanup_pt)(void *data);
34 | typedef void (*ngx_stream_request_cleanup_pt)(void *data);
35 |
36 | #define NGX_STREAM_REQUEST_ERROR (ngx_stream_request_t*)NGX_ERROR
37 | #define NGX_STREAM_REQUEST_AGAIN (ngx_stream_request_t*)NULL
38 |
39 | #define ngx_stream_request_get_module_ctx(r, module) (r)->ctx[module.ctx_index]
40 | #define ngx_stream_request_set_ctx(r, c, module) r->ctx[module.ctx_index] = c;
41 | #define ngx_stream_request_delete_ctx(r, module) r->ctx[module.ctx_index] = NULL;
42 |
43 | extern void ngx_stream_finalize_session_r(ngx_stream_session_t *s, char* reason);
44 | extern void ngx_stream_finalize_session_r_level(ngx_stream_session_t *s
45 | , char* reason
46 | , ngx_uint_t level);
47 | extern ngx_stream_request_t* ngx_stream_new_request(ngx_stream_session_t*);
48 | /* run loop */
49 | extern void ngx_stream_handle_request(ngx_stream_request_t*);
50 | // 从index个的response方向开始处理request. response: 1/0
51 | // index < 0 表示从后向前的index. -1: 最后一个
52 | extern void ngx_stream_handle_request_from(ngx_stream_request_t*
53 | , ngx_int_t index, ngx_int_t response);
54 |
55 | extern ngx_stream_request_handler_t* ngx_stream_request_add_handler(ngx_conf_t*);
56 |
57 | extern void ngx_stream_request_regular_data(ngx_stream_request_t*);
58 | extern void ngx_stream_request_set_data(ngx_stream_request_t*, char* err_info);
59 |
60 | extern ngx_stream_cleanup_t * ngx_stream_cleanup_add(ngx_stream_session_t *s);
61 | extern ngx_stream_request_cleanup_t *
62 | ngx_stream_request_cleanup_add(ngx_stream_request_t*);
63 |
64 | extern ngx_module_t ngx_stream_request_core_module;
65 | /* protolcol must set this function to ngx_stream_core_srv_conf_t->handler */
66 | extern void ngx_stream_request_core_handler(ngx_stream_session_t *s);
67 |
68 | extern void ngx_regular_buf(ngx_buf_t* buf);
69 | extern ngx_uint_t ngx_chain_len(ngx_chain_t* chain);
70 | extern ngx_array_t* ngx_merge_key_val_array(ngx_pool_t* pool, ngx_array_t* parent
71 | , ngx_array_t* child);
72 |
73 | #define NGX_STREAM_REQUEST_SUBPROTOCOL_ANY -1
74 |
75 | struct ngx_stream_request_s{
76 | ngx_stream_session_t* session;
77 | ngx_stream_request_upstream_t* upstream;
78 |
79 | ngx_pool_t* pool;
80 |
81 | // NGX_STREAM_REQUEST_SUBPROTOCOL_ANY: 表示不关注具体的子协议
82 | ngx_int_t subprotocol_flag;
83 |
84 | ngx_chain_t* data; // in / out
85 | ngx_int_t error; // 标示data中的数据
86 |
87 | void** ctx;
88 |
89 | ngx_stream_request_variable_value_t *variables;
90 | #if (NGX_PCRE)
91 | ngx_uint_t ncaptures;
92 | int *captures;
93 | u_char *captures_data;
94 | #endif
95 |
96 | ngx_stream_request_cleanup_t* cln;
97 |
98 | char* close_reason; // 当数据发送结束时,是否关闭连接,和关闭原因
99 |
100 | ngx_queue_t list;
101 | } ;
102 |
103 | struct ngx_stream_cleanup_s {
104 | ngx_stream_cleanup_pt handler;
105 | void *data;
106 | ngx_stream_cleanup_t *next;
107 | };
108 |
109 | struct ngx_stream_request_cleanup_s {
110 | ngx_stream_request_cleanup_pt handler;
111 | void *data;
112 | ngx_stream_request_cleanup_t *next;
113 | };
114 |
115 | typedef struct {
116 | ngx_hash_t variables_hash;
117 |
118 | ngx_array_t variables; /* ngx_stream_variable_t */
119 | ngx_array_t prefix_variables; /* ngx_stream_variable_t */
120 | ngx_uint_t ncaptures;
121 |
122 | ngx_uint_t variables_hash_max_size;
123 | ngx_uint_t variables_hash_bucket_size;
124 |
125 | ngx_hash_keys_arrays_t *variables_keys;
126 |
127 | } ngx_stream_request_core_main_conf_t;
128 |
129 | struct ngx_stream_request_handler_s{
130 | // NGX_STREAM_REQUEST_SUBPROTOCOL_ANY: 表示不关注具体的子协议
131 | ngx_int_t subprotocol_flag;
132 | ngx_int_t index; // set by ngx_stream_request_add_handler
133 | char* name;
134 | /* NGX_OK; NGX_AGAIN; NGX_ERROR; NGX_HANDLER_STOP */
135 | ngx_int_t (*handle_request)(ngx_stream_request_t*);
136 | ngx_int_t (*build_response)(ngx_stream_request_t*);
137 | };
138 |
139 | struct ngx_stream_request_protocol_s {
140 | void (*init_parser)(ngx_stream_session_t*);
141 | ngx_stream_request_t* (*get_request)(ngx_stream_session_t*);
142 |
143 | ngx_stream_request_handler_t handler;
144 | };
145 |
146 | struct ngx_stream_request_core_srv_conf_s{
147 | // client
148 | ngx_msec_t heartbeat;
149 | ngx_msec_t receive_from_client_timeout;
150 | ngx_msec_t send_to_client_timeout;
151 |
152 | // upstream
153 | ngx_msec_t send_to_proxy_timeout;
154 | ngx_msec_t receive_from_proxy_timeout;
155 | ngx_msec_t proxy_response_timeout;
156 | ngx_msec_t next_upstream_timeout; //查找next upstream 的最长时间
157 | ngx_uint_t next_upstream_tries; //next upstream 的最大重试次数
158 | ngx_flag_t next_upstream; //是否自动寻找下一个
159 | ngx_msec_t connect_timeout; // connect upstream 的超时时间
160 |
161 | ngx_addr_t *local;
162 |
163 | ngx_stream_upstream_srv_conf_t* upstream;
164 |
165 | ngx_stream_request_protocol_t protocol;
166 |
167 | ngx_array_t handlers; /* ngx_stream_request_handler_t */
168 | };
169 |
170 |
171 | #endif /* ngx_stream_request_h */
172 |
173 |
174 |
--------------------------------------------------------------------------------
/client/js/dest/stringview.min.js:
--------------------------------------------------------------------------------
1 | !function(e){"use strict";function t(e,r,n,a){var i,o,h,s,c,f,g=isFinite(n)?n:0,u=15;r&&(this.encoding=r.toString());e:switch(this.encoding){case"UTF-8":s=t.putUTF8CharCode,c=t.getUTF8CharLength,i=Uint8Array;break e;case"UTF-16":s=t.putUTF16CharCode,c=t.getUTF16CharLength,i=Uint16Array;break e;case"UTF-32":i=Uint32Array,u&=14;break e;default:i=Uint8Array,u&=14}e:switch(typeof e){case"string":u&=7;break e;case"object":switch(e.constructor){case t:u&=3;break e;case String:u&=7;break e;case ArrayBuffer:o=new i(e),f="UTF-32"===this.encoding?e.byteLength>>>2:"UTF-16"===this.encoding?e.byteLength>>>1:e.byteLength,h=0!==g||isFinite(a)&&a!==f?new i(e,g,isFinite(a)?a:f-g):o;break e;case Uint32Array:case Uint16Array:case Uint8Array:i=e.constructor,f=e.length,o=0===e.byteOffset&&e.length===(i===Uint32Array?e.buffer.byteLength>>>2:i===Uint16Array?e.buffer.byteLength>>>1:e.buffer.byteLength)?e:new i(e.buffer),h=0!==g||isFinite(a)&&a!==f?e.subarray(g,isFinite(a)?g+a:f):e;break e;default:o=new i(e),f=o.length,h=0!==g||isFinite(a)&&a!==f?o.subarray(g,isFinite(a)?g+a:f):o}break e;default:o=h=new i(Number(e)||0)}if(u<8){var d,U,F,b,T,l,C;4&u?(d=e,U=f=d.length,u^="UTF-32"===this.encoding?0:2,g=F=n?Math.max((U+n)%U,0):0,T=b=(Number.isInteger(a)?Math.min(Math.max(a,0)+g,U):U)-1):(d=e.rawData,f=e.makeIndex(),g=F=n?Math.max((f+n)%f,0):0,U=Number.isInteger(a)?Math.min(Math.max(a,0),f-F):f,T=b=U+F,"UTF-8"===e.encoding?(l=t.getUTF8CharLength,C=t.loadUTF8CharCode):"UTF-16"===e.encoding?(l=t.getUTF16CharLength,C=t.loadUTF16CharCode):u&=1),(0===U||u<4&&d.encoding===this.encoding&&0===F&&U===f)&&(u=7);e:switch(u){case 0:o=new i(U);for(var w=0;wF&&(U+=c(m));o=new i(U);for(var y=g,w=0;w3&&(g>0||T-9007199254740992&&e<9007199254740992&&Math.floor(e)===e}),t.loadUTF8CharCode=function(e,t){var r=e.length,n=e[t];return n>251&&n<254&&t+5247&&n<252&&t+4239&&n<248&&t+3223&&n<240&&t+2191&&n<224&&t+1>>6),e[n++]=128+(63&t)):t<65536?(e[n++]=224+(t>>>12),e[n++]=128+(t>>>6&63),e[n++]=128+(63&t)):t<2097152?(e[n++]=240+(t>>>18),e[n++]=128+(t>>>12&63),e[n++]=128+(t>>>6&63),e[n++]=128+(63&t)):t<67108864?(e[n++]=248+(t>>>24),e[n++]=128+(t>>>18&63),e[n++]=128+(t>>>12&63),e[n++]=128+(t>>>6&63),e[n++]=128+(63&t)):(e[n++]=252+t/1073741824,e[n++]=128+(t>>>24&63),e[n++]=128+(t>>>18&63),e[n++]=128+(t>>>12&63),e[n++]=128+(t>>>6&63),e[n++]=128+(63&t)),n},t.getUTF8CharLength=function(e){return e<128?1:e<2048?2:e<65536?3:e<2097152?4:e<67108864?5:6},t.loadUTF16CharCode=function(e,t){var r=e[t];return r>55231&&t+1>>10),e[n++]=56320+(1023&t)),n},t.getUTF16CharLength=function(e){return e<65536?1:2},t.b64ToUint6=function(e){return e>64&&e<91?e-65:e>96&&e<123?e-71:e>47&&e<58?e+4:43===e?62:47===e?63:0},t.uint6ToB64=function(e){return e<26?e+65:e<52?e+71:e<62?e-4:62===e?43:63===e?47:65},t.bytesToBase64=function(e){for(var r,n="",a=e.length,i=0,o=0;o>>r&24),2!==r&&e.length-o!==1||(n+=String.fromCharCode(t.uint6ToB64(i>>>18&63),t.uint6ToB64(i>>>12&63),t.uint6ToB64(i>>>6&63),t.uint6ToB64(63&i)),i=0);return n.replace(/A(?=A$|$)/g,"=")},t.base64ToBytes=function(e,r){for(var n,a,i=e.replace(/[^A-Za-z0-9\+\/]/g,""),o=i.length,h=r?Math.ceil((3*o+1>>>2)/r)*r:3*o+1>>>2,s=new Uint8Array(h),c=0,f=0,g=0;g>>(16>>>n&24)&255;c=0}return s},t.makeFromBase64=function(e,r,n,a){return new t("UTF-16"===r||"UTF-32"===r?t.base64ToBytes(e,"UTF-16"===r?2:4).buffer:t.base64ToBytes(e),r,n,a)},t.prototype.encoding="UTF-8",t.prototype.makeIndex=function(e,t){var r,n=this.rawData,a=n.length,i=t||0,o=i,h=isNaN(e)?1/0:e;if(e+1>n.length)throw new RangeError("StringView.prototype.makeIndex - The offset can't be major than the length of the array - 1.");switch(this.encoding){case"UTF-8":var s;for(r=0;o251&&s<254&&o+5247&&s<252&&o+4239&&s<248&&o+3223&&s<240&&o+2191&&s<224&&o+155231&&o+1o?o-a:r:o,0===a&&i===o?this:(h?(s=this.makeIndex(a),n=this.makeIndex(i,s)-s):(s=a,n=i-a),"UTF-16"===this.encoding?s<<=1:"UTF-32"===this.encoding&&(s<<=2),new t(this.buffer,this.encoding,s,n)))},t.prototype.forEachChar=function(e,r,n,a){var i,o,h=this.rawData;if("UTF-8"===this.encoding||"UTF-16"===this.encoding){var s,c;"UTF-8"===this.encoding?(s=t.getUTF8CharLength,c=t.loadUTF8CharCode):"UTF-16"===this.encoding&&(s=t.getUTF16CharLength,c=t.loadUTF16CharCode),o=isFinite(n)?this.makeIndex(n):0,i=isFinite(a)?this.makeIndex(a,o):h.length;for(var f,g=0;oheaders
83 | , RequestCallback callback){
84 | if (net_ == null) {
85 | callback.onComplete();
86 | callback.onFailed("host and port not set!");
87 | return;
88 | }
89 | if (handler_ == null) {
90 | callback.onComplete();
91 | callback.onFailed("async Event Handler not set!");
92 | return;
93 | }
94 |
95 | long id = reqID();
96 | Request request = new Request();
97 | request.body = body;
98 | request.headers = headers;
99 | request.requestCallback = callback;
100 | request.reqID = id;
101 |
102 | requests_.put(id, request);
103 |
104 | if (net_.status() == Net.Status.Open) {
105 | sendRequest(body, headers, id);
106 | return;
107 | }
108 | if (net_.status() == Net.Status.Connecting) {
109 | return;
110 | }
111 | connect();
112 | }
113 |
114 | public Client() {
115 | reqID_ = reqIDstart;
116 | net_ = null;
117 | protocol_ = new DefaultContentProtocol();
118 | requests_ = new HashMap();
119 | ca_ = null;
120 | delegate_ = new Delegate() {
121 | @Override
122 | public void onPush(byte[] data) {
123 | // TODO debug log
124 | }
125 | };
126 | config_ = new Net.Config();
127 | config_.hearbeatTime_ms = 4*60*1000;
128 | config_.translatioin_ms = 10*1000;
129 | config_.connectTimeout_ms = 30*1000;
130 | }
131 |
132 | public void setDelegate(Delegate delegate) {
133 | this.delegate_ = delegate;
134 | }
135 |
136 | // ---- private class ----
137 | private class Request {
138 | long reqID;
139 | byte[] body;
140 | Map headers;
141 | RequestCallback requestCallback;
142 | }
143 |
144 | private interface MessageHandler {
145 | public void handle(byte[] message);
146 | }
147 |
148 | private long reqID(){
149 | reqID_++;
150 | if (reqID_ < reqIDstart || reqID_ > Integer.MAX_VALUE) {
151 | reqID_ = reqIDstart;
152 | }
153 | return reqID_;
154 | }
155 |
156 | private void connect(){
157 | normalMessageHandler_ = new MessageHandler() {
158 | @Override
159 | public void handle(byte[] message) {
160 | Response response = protocol_.parse(message);
161 |
162 | if (response.reqID == pushID) {
163 | Client.this.delegate_.onPush(response.data);
164 | return;
165 | }
166 |
167 | Request request = Client.this.requests_.get(response.reqID);
168 | if (request == null) {
169 | // System.out.println("not find request");
170 | return;
171 | }
172 | request.requestCallback.onComplete();
173 | if (response.status != Response.Status.Success) {
174 | if (response.data == null) {
175 | request.requestCallback.onFailed("may be server error, but server has closed the error log");
176 | } else {
177 | try {
178 | request.requestCallback.onFailed(new String(response.data, "UTF-8"));
179 | } catch (java.io.UnsupportedEncodingException e) {
180 | request.requestCallback.onFailed("unkown error, because java utf-8 error");
181 | }
182 | }
183 | } else {
184 | request.requestCallback.onSuccess(response.data);
185 | }
186 |
187 | Client.this.requests_.remove(response.reqID);
188 | }
189 | };
190 | this.messageHandler_ = normalMessageHandler_;
191 |
192 | net_.open();
193 | }
194 |
195 | private void sendAllRequests(){
196 | for (Request request : requests_.values()) {
197 | sendRequest(request.body, request.headers, request.reqID);
198 | }
199 | }
200 |
201 | private void sendRequest(byte[] body, Mapheaders, final long reqID){
202 | byte[] data = protocol_.build(body, headers, reqID);
203 | if (data == null) {
204 | net_.postTask(new Net.Task() {
205 | public void run() {
206 | Client.this.messageHandler_.handle(Client.this.protocol_.buildFailedMessage("build message error, maybe length of headers' key or value > 255, or is not asscii", reqID));
207 | }
208 | });
209 | return;
210 | }
211 |
212 | net_.send(data);
213 | }
214 |
215 | private void errorAllRequests(String error){ // async call
216 | ArrayList requests = new ArrayList<>(requests_.size());
217 | requests.addAll(requests_.values());
218 | for (Request request : requests) {
219 | normalMessageHandler_.handle(protocol_.buildFailedMessage(error, request.reqID));
220 | }
221 | try {
222 | requests_.clear();
223 | } catch (UnsupportedOperationException e) {
224 | requests_ = new HashMap();
225 | }
226 | }
227 |
228 | private Net net_;
229 | private NetCallback netCallback_;
230 | private ContentProtocol protocol_;
231 | private Map requests_;
232 | private long reqID_;
233 | private MessageHandler messageHandler_;
234 | private MessageHandler normalMessageHandler_;
235 | private Delegate delegate_;
236 | private AsyncEventHandler handler_;
237 | private Net.Config config_;
238 | private X509Certificate ca_;
239 |
240 | private static final long reqIDstart = 200;
241 | private static final long pushID = 1; // need equal server
242 | }
243 |
--------------------------------------------------------------------------------
/client/ios/ios-sdk/ios-sdk/main.m:
--------------------------------------------------------------------------------
1 | //
2 | // main.m
3 | // ios-sdk
4 | //
5 | // Created by xpwu on 2016/11/23.
6 | // Copyright © 2016年 xpwuxpwu. All rights reserved.
7 | //
8 |
9 | #import
10 |
11 | #import "STMClient.h"
12 |
13 | @interface RunLoopSource : NSObject
14 | -(void)perform:(id)message;
15 | @end
16 |
17 | @implementation RunLoopSource
18 | -(void)perform:(id)message {
19 | void (^msg)(void) = message;
20 | msg();
21 | }
22 | @end
23 |
24 | #define RUNLOOP_INIT \
25 | RunLoopSource* src = [[RunLoopSource alloc]init]; \
26 | [[NSRunLoop mainRunLoop]performSelector:@selector(perform:) \
27 | target:src argument:^(void) {
28 |
29 |
30 | #define RUNLOOP_RUN \
31 | } \
32 | order:0 modes:@[NSDefaultRunLoopMode]]; \
33 | \
34 | [[NSRunLoop mainRunLoop]run];
35 |
36 |
37 | int main(int argc, const char * argv[]) {
38 | @autoreleasepool {
39 |
40 | RUNLOOP_INIT
41 |
42 | STMClient* client = [[STMClient alloc]init];
43 |
44 | STMClient* __weak client_ = client;
45 | [client setConnectHost:@"ssl://www.xpwu.me" port:10005
46 | onSuccess:^{
47 | NSLog(@"connect successful");
48 | }
49 | onFailed:^(NSString * error) {
50 | NSLog(@"connect failed: %@", error);
51 | [client_ addRequestBody:[@"add message" dataUsingEncoding:NSUTF8StringEncoding]
52 | headers:@{@"h":@"test", @"ua": @"request ua"}
53 | onSuccess:^(NSData * data) {
54 | NSLog(@"%@", [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);
55 | }
56 | onFailed:^(NSString * error) {
57 | NSLog(@"%@", error);
58 | }
59 | onComplete:^{
60 | NSLog(@"request complete");
61 | }];
62 | }];
63 |
64 | client.onpush = ^(NSData* data) {
65 | NSLog(@"[push]---%@", [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);
66 | };
67 |
68 | [client setBlockRequestOnConnected:[@"block message" dataUsingEncoding:NSUTF8StringEncoding]
69 | headers:@{@"name": @"block message"}
70 | onSuccess:^BOOL(NSData * data) {
71 | NSLog(@"%@", [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);
72 | return YES;
73 | }
74 | onFailed:^(NSString * error) {
75 | NSLog(@"%@", error);
76 | }
77 | onComplete:^{
78 | NSLog(@"block message complete");
79 | }];
80 |
81 | [client addRequestBody:[@"add message" dataUsingEncoding:NSUTF8StringEncoding]
82 | headers:@{@"h":@"test", @"ua": @"request ua"}
83 | onSuccess:^(NSData * data) {
84 | NSLog(@"%@", [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);
85 | }
86 | onFailed:^(NSString * error) {
87 | NSLog(@"%@", error);
88 | }
89 | onComplete:^{
90 | NSLog(@"request complete");
91 | }];
92 |
93 | [client addRequestBody:nil
94 | headers:@{@"h":@"test", @"ua": @"request ua 2"}
95 | onSuccess:^(NSData * data) {
96 | NSLog(@"%@", [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);
97 | }
98 | onFailed:^(NSString * error) {
99 | NSLog(@"%@", error);
100 | }
101 | onComplete:^{
102 | NSLog(@"request complete");
103 | }];
104 |
105 | [client addRequestBody:nil
106 | headers:nil
107 | onSuccess:^(NSData * data) {
108 | NSLog(@"%@", [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);
109 | }
110 | onFailed:^(NSString * error) {
111 | NSLog(@"%@", error);
112 | }
113 | onComplete:^{
114 | NSLog(@"request complete");
115 | }];
116 |
117 | [client addRequestBody:nil
118 | headers:@{@"h":@"test", @"ua NSLog(, [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);ua NSLog(, [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);ua NSLog(, [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);ua NSLog(, [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);ua NSLog(, [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);ua NSLog(, [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);ua NSLog(, [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);ua NSLog(, [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);ua NSLog(, [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);ua NSLog(, [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);ua NSLog(, [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);ua NSLog(, [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);ua NSLog(, [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);ua NSLog(, [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);ua NSLog(, [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);ua NSLog(, [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);ua NSLog(, [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);ua NSLog(, [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);ua NSLog(, [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);ua NSLog(, [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);ua NSLog(, [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);ua NSLog(, [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);ua NSLog(, [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);ua NSLog(, [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);ua NSLog(, [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);ua NSLog(, [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);ua NSLog(, [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);ua NSLog(, [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);ua NSLog(, [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);ua NSLog(, [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);": @"request ua 2"}
119 | onSuccess:^(NSData * data) {
120 | NSLog(@"%@", [[NSString alloc]initWithData:data encoding:NSUTF8StringEncoding]);
121 | }
122 | onFailed:^(NSString * error) {
123 | NSLog(@"%@", error);
124 | }
125 | onComplete:^{
126 | NSLog(@"request complete");
127 | }];
128 |
129 | RUNLOOP_RUN
130 |
131 | }
132 | return 0;
133 | }
134 |
--------------------------------------------------------------------------------
/stream_module/ngx_stream_request_core_module/ngx_stream_request_upstream.c:
--------------------------------------------------------------------------------
1 | //
2 | // ngx_stream_request_upstream.c
3 | // nginx-1.12
4 | //
5 | // Created by xpwu on 2017/12/16.
6 | // Copyright © 2017年 xpwu. All rights reserved.
7 | //
8 |
9 | #include
10 | #include
11 | #include
12 |
13 | static void ngx_stream_request_proxy_connect_handler(ngx_event_t *ev);
14 | static ngx_int_t ngx_stream_request_core_test_connect(ngx_connection_t *c);
15 | static void ngx_stream_request_core_next_upstream(ngx_stream_request_t *r);
16 | static void ngx_stream_proxy_init_upstream(ngx_stream_request_t *r);
17 |
18 | static void empty_handler(ngx_event_t *ev){}
19 |
20 | static ngx_int_t
21 | ngx_stream_request_core_test_connect(ngx_connection_t *c)
22 | {
23 | int err;
24 | socklen_t len;
25 |
26 | #if (NGX_HAVE_KQUEUE)
27 |
28 | if (ngx_event_flags & NGX_USE_KQUEUE_EVENT) {
29 | err = c->write->kq_errno ? c->write->kq_errno : c->read->kq_errno;
30 |
31 | if (err) {
32 | (void) ngx_connection_error(c, err,
33 | "kevent() reported that connect() failed");
34 | return NGX_ERROR;
35 | }
36 |
37 | } else
38 | #endif
39 | {
40 | err = 0;
41 | len = sizeof(int);
42 |
43 | /*
44 | * BSDs and Linux return 0 and set a pending error in err
45 | * Solaris returns -1 and sets errno
46 | */
47 |
48 | if (getsockopt(c->fd, SOL_SOCKET, SO_ERROR, (void *) &err, &len)
49 | == -1)
50 | {
51 | err = ngx_socket_errno;
52 | }
53 |
54 | if (err) {
55 | (void) ngx_connection_error(c, err, "connect() failed");
56 | return NGX_ERROR;
57 | }
58 | }
59 |
60 | return NGX_OK;
61 | }
62 |
63 | static void
64 | ngx_stream_request_core_next_upstream(ngx_stream_request_t *r)
65 | {
66 | ngx_msec_t timeout;
67 | ngx_connection_t *pc;
68 | ngx_stream_upstream_t *u;
69 | ngx_stream_request_core_srv_conf_t *pscf;
70 |
71 | ngx_log_debug0(NGX_LOG_DEBUG_STREAM, r->session->connection->log, 0,
72 | "stream proxy next upstream");
73 |
74 | u = &r->upstream->upstream;
75 |
76 | if (u->peer.sockaddr) {
77 | u->peer.free(&u->peer, u->peer.data, NGX_PEER_FAILED);
78 | u->peer.sockaddr = NULL;
79 | }
80 |
81 | pscf = ngx_stream_get_module_srv_conf(r->session, ngx_stream_request_core_module);
82 |
83 | timeout = pscf->next_upstream_timeout;
84 |
85 | if (u->peer.tries == 0
86 | || !pscf->next_upstream
87 | || (timeout && ngx_current_msec - u->peer.start_time >= timeout))
88 | {
89 | r->upstream->upstream_connect_failed(r, "has not upstream");
90 | return;
91 | }
92 |
93 | pc = u->peer.connection;
94 |
95 | if (pc) {
96 | ngx_log_debug1(NGX_LOG_DEBUG_STREAM, r->session->connection->log, 0,
97 | "close proxy upstream connection: %d", pc->fd);
98 |
99 | ngx_close_connection(pc);
100 | u->peer.connection = NULL;
101 | }
102 |
103 | ngx_stream_request_upstream_connect(r);
104 | }
105 |
106 | void
107 | ngx_stream_request_upstream_connect(ngx_stream_request_t *r)
108 | {
109 | ngx_int_t rc;
110 | ngx_connection_t *c, *pc;
111 | ngx_stream_upstream_t *u;
112 | ngx_stream_request_core_srv_conf_t *pscf;
113 | ngx_stream_session_t* s;
114 |
115 | s = r->session;
116 | c = s->connection;
117 |
118 | // c->log->action = "";
119 |
120 | u = &r->upstream->upstream;
121 |
122 | rc = ngx_event_connect_peer(&u->peer);
123 |
124 |
125 | #ifdef NGX_DEBUG
126 | char* rc_s = "";
127 | switch (rc) {
128 | case -1:
129 | rc_s = "NGX_ERROR";
130 | break;
131 | case -2:
132 | rc_s = "NGX_AGAIN";
133 | break;
134 | case -3:
135 | rc_s = "NGX_BUSY";
136 | break;
137 | default:
138 | rc_s = "-4: NGX_DONE; -5:NGX_DECLINED; -6:NGX_ABORT";
139 | break;
140 | }
141 | #endif
142 |
143 | ngx_log_debug2(NGX_LOG_DEBUG_STREAM, c->log, 0
144 | , "proxy connect: %i, %s", rc, rc_s);
145 |
146 | if (rc == NGX_ERROR) {
147 | r->upstream->upstream_connect_failed(r, "connect upsteam peer error");
148 | return;
149 | }
150 |
151 | if (rc == NGX_BUSY) {
152 | r->upstream->upstream_connect_failed(r, "no live upstreams");
153 | return;
154 | }
155 |
156 | if (rc == NGX_DECLINED) {
157 | ngx_stream_request_core_next_upstream(r);
158 | return;
159 | }
160 |
161 | /* rc == NGX_OK || rc == NGX_AGAIN || rc == NGX_DONE */
162 |
163 | pc = u->peer.connection;
164 |
165 | pc->data = r;
166 | pc->log = c->log;
167 | pc->pool = r->pool;
168 | pc->read->log = c->log;
169 | pc->write->log = c->log;
170 |
171 | if (rc != NGX_AGAIN) {
172 | ngx_stream_proxy_init_upstream(r);
173 | return;
174 | }
175 |
176 | pc->read->handler = ngx_stream_request_proxy_connect_handler;
177 | pc->write->handler = ngx_stream_request_proxy_connect_handler;
178 |
179 | pscf = ngx_stream_get_module_srv_conf(s, ngx_stream_request_core_module);
180 |
181 | ngx_add_timer(pc->write, pscf->connect_timeout);
182 | }
183 |
184 | static void
185 | ngx_stream_proxy_init_upstream(ngx_stream_request_t *r)
186 | {
187 | int tcp_nodelay;
188 | // u_char *p;
189 | ngx_connection_t *c, *pc;
190 | ngx_log_handler_pt handler;
191 | ngx_stream_upstream_t *u;
192 | ngx_stream_core_srv_conf_t *cscf;
193 | ngx_stream_session_t* s = r->session;
194 |
195 | u = &r->upstream->upstream;
196 | pc = u->peer.connection;
197 |
198 | cscf = ngx_stream_get_module_srv_conf(s, ngx_stream_core_module);
199 |
200 | if (pc->type == SOCK_STREAM
201 | && cscf->tcp_nodelay
202 | && pc->tcp_nodelay == NGX_TCP_NODELAY_UNSET)
203 | {
204 | ngx_log_debug0(NGX_LOG_DEBUG_STREAM, pc->log, 0, "tcp_nodelay");
205 |
206 | tcp_nodelay = 1;
207 |
208 | if (setsockopt(pc->fd, IPPROTO_TCP, TCP_NODELAY,
209 | (const void *) &tcp_nodelay, sizeof(int)) == -1)
210 | {
211 | ngx_connection_error(pc, ngx_socket_errno,
212 | "setsockopt(TCP_NODELAY) failed");
213 | ngx_stream_request_core_next_upstream(r);
214 | return;
215 | }
216 |
217 | pc->tcp_nodelay = NGX_TCP_NODELAY_SET;
218 | }
219 |
220 | c = s->connection;
221 |
222 | if (c->log->log_level >= NGX_LOG_INFO) {
223 | ngx_str_t str;
224 | u_char addr[NGX_SOCKADDR_STRLEN];
225 |
226 | str.len = NGX_SOCKADDR_STRLEN;
227 | str.data = addr;
228 |
229 | if (ngx_connection_local_sockaddr(pc, &str, 1) == NGX_OK) {
230 | handler = c->log->handler;
231 | c->log->handler = NULL;
232 |
233 | ngx_log_error(NGX_LOG_INFO, c->log, 0,
234 | "%sproxy %V connected to %V",
235 | pc->type == SOCK_DGRAM ? "udp " : "",
236 | &str, u->peer.name);
237 |
238 | c->log->handler = handler;
239 | }
240 | }
241 |
242 | u->connected = 1;
243 |
244 | pc->read->handler = empty_handler;
245 | pc->write->handler = empty_handler;
246 |
247 | r->upstream->upstream_connected(r);
248 | }
249 |
250 | static void
251 | ngx_stream_request_proxy_connect_handler(ngx_event_t *ev)
252 | {
253 | ngx_connection_t *c;
254 | // ngx_stream_session_t *s;
255 | ngx_stream_request_t* r;
256 |
257 | c = ev->data;
258 | r = c->data;
259 | // s = r->session;
260 |
261 | if (ev->timedout) {
262 | ngx_log_error(NGX_LOG_ERR, c->log, NGX_ETIMEDOUT, "upstream timed out");
263 | ngx_stream_request_core_next_upstream(r);
264 | return;
265 | }
266 |
267 | if (ev->timer_set) {
268 | ngx_del_timer(ev);
269 | }
270 |
271 | ngx_log_debug0(NGX_LOG_DEBUG_STREAM, c->log, 0,
272 | "stream proxy connect upstream");
273 |
274 | if (ngx_stream_request_core_test_connect(c) != NGX_OK) {
275 | ngx_stream_request_core_next_upstream(r);
276 | return;
277 | }
278 |
279 | ngx_stream_proxy_init_upstream(r);
280 | }
281 |
282 |
283 |
--------------------------------------------------------------------------------
/client/ios/STMClient.m:
--------------------------------------------------------------------------------
1 | //
2 | // STMClient.m
3 | // ios-sdk
4 | //
5 | // Created by xpwu on 2016/11/24.
6 | // Copyright © 2016年 xpwu.xpwu. All rights reserved.
7 | //
8 |
9 | #import "STMClient.h"
10 | #import "STMNet.h"
11 | #import "STMDefaultContentProtocol.h"
12 | #import "Log.h"
13 |
14 | const uint32_t reqIDstart = 200;
15 | const uint32_t pushID = 1; // need equal server
16 |
17 | @interface Request : NSObject
18 | @property(nonatomic) uint32_t reqID;
19 | @property(nonatomic) NSData* body;
20 | @property(nonatomic) NSDictionary* headers;
21 | @property(nonatomic) void (^suc)(NSData*);
22 | @property(nonatomic) BOOL (^sucOnlyForBlock)(NSData*);
23 | @property(nonatomic) void (^failed)(NSString*);
24 | @property(nonatomic) void (^complete)();
25 | @end
26 |
27 | @implementation Request @end
28 |
29 | @interface STMClient () {
30 | STMNet* net_;
31 | NSMutableDictionary* requests_;
32 | id protocol_;
33 |
34 | uint32_t reqID_;
35 |
36 | void (^onConnectionSuc_)(void);
37 | void (^onConnectionFaild_)(NSString*);
38 |
39 | void (^normalOnMessage_)(NSData*);
40 |
41 | NSTimeInterval ctime_;
42 | NSTimeInterval htime_;
43 | NSTimeInterval ttime_;
44 | }
45 | -(uint32_t)reqID;
46 | -(void)connect;
47 | -(void)postMessage:(void(^)(void))message;
48 | -(void)performMessageByRunLoop_:(id)message;
49 | -(void)sendAllRequests;
50 | -(void)setOnMessageToNormal;
51 | -(void)sendRequest:(NSData*)body
52 | withHeader:(NSDictionary*)header
53 | andReqID:(uint32_t)reqid;
54 | -(void)errorAllRequests:(NSString*)error;
55 | @end
56 |
57 | @implementation STMClient
58 | -(instancetype)init {
59 | if (self = [super init]) {
60 | reqID_ = reqIDstart;
61 | net_ = nil;
62 | protocol_ = [[STMDefaultContentProtocol alloc]init];
63 | self.onpush = ^(NSData* data){NSLog(@"receive push data");};
64 | requests_ = [[NSMutableDictionary alloc]init];
65 |
66 | ctime_ = 30;
67 | htime_ = 4*60;
68 | ttime_ = 10;
69 | }
70 | return self;
71 | }
72 |
73 | -(void)dealloc {
74 | [net_ close];
75 | }
76 |
77 | -(void)setConfigConnectionTimeout:(NSTimeInterval)ctime
78 | heartbeat:(NSTimeInterval)htime
79 | transmission:(NSTimeInterval)ttime {
80 | ctime_ = ctime;
81 | htime_ = htime;
82 | ttime_ = ttime;
83 | }
84 |
85 | -(void)setConnectHost:(NSString*)host
86 | port:(uint16_t)port {
87 | [self setConnectHost:host port:port onSuccess:nil onFailed:nil];
88 | }
89 |
90 | -(void)setConnectHost:(NSString*)host
91 | port:(uint16_t)port
92 | onSuccess:(void (^)(void))suc {
93 | [self setConnectHost:host port:port onSuccess:suc onFailed:nil];
94 | }
95 |
96 | -(void)setConnectHost:(NSString*)host
97 | port:(uint16_t)port
98 | onSuccess:(void (^)(void))suc
99 | onFailed:(void (^)(NSString*))failed {
100 | net_ = [[STMNet alloc]initWithHost:host andPort:port];
101 | onConnectionSuc_ = suc;
102 | onConnectionFaild_ = failed;
103 | net_.hearbeatTime = htime_;
104 | net_.transmissionTimeout = ttime_;
105 | net_.openTimeout = ctime_;
106 | }
107 |
108 | -(void)addRequestBody:(NSData*)body
109 | onSuccess:(void (^)(NSData*))suc {
110 | [self addRequestBody:body headers:nil onSuccess:suc onFailed:nil onComplete:nil];
111 | }
112 |
113 | -(void)addRequestBody:(NSData*)body
114 | headers:(NSDictionary*)headers
115 | onSuccess:(void (^)(NSData*))suc {
116 | [self addRequestBody:body headers:headers onSuccess:suc onFailed:nil onComplete:nil];
117 | }
118 |
119 | -(void)addRequestBody:(NSData*)body
120 | headers:(NSDictionary*)headers
121 | onSuccess:(void (^)(NSData*))suc
122 | onFailed:(void (^)(NSString*))failed {
123 | [self addRequestBody:body headers:headers onSuccess:suc onFailed:failed onComplete:nil];
124 | }
125 |
126 | -(void)addRequestBody:(NSData*)body
127 | headers:(NSDictionary*)headers
128 | onSuccess:(void (^)(NSData*))suc
129 | onFailed:(void (^)(NSString*))failed
130 | onComplete:(void (^)())complete {
131 | if (net_ == nil) {
132 | if (complete != nil) {
133 | complete();
134 | }
135 | if (failed != nil) {
136 | failed(@"host and port not set!");
137 | }
138 | return;
139 | }
140 |
141 | uint32_t reqid = [self reqID];
142 | Request* req = [[Request alloc]init];
143 | req.body = body;
144 | req.headers = headers;
145 | req.suc = suc;
146 | req.failed = failed;
147 | req.complete = complete;
148 | req.reqID = reqid;
149 |
150 | [requests_ setObject:req forKey:[NSNumber numberWithInt:reqid]];
151 |
152 | if (net_.status == STMNetStatusOpen) {
153 | [self sendRequest:body withHeader:headers andReqID:reqid];
154 | return;
155 | }
156 | if (net_.status == STMNetStatusConnecting) {
157 | return;
158 | }
159 | [self connect];
160 | }
161 |
162 | #pragma mark - private
163 |
164 | -(uint32_t)reqID {
165 | reqID_ = reqID_+1;
166 |
167 | if (reqID_ < reqIDstart) {
168 | reqID_ = reqIDstart;
169 | }
170 |
171 | return reqID_;
172 | }
173 |
174 | #define defineWEAK(arg) __weak __typeof(arg) _weak_##arg = arg
175 | #define defineWEAK_TYPE(type, arg) type _weak_##arg = arg
176 | #define weak(arg) _weak_##arg
177 |
178 | -(void)connect {
179 | defineWEAK(protocol_);
180 | defineWEAK(self);
181 | defineWEAK(requests_);
182 |
183 | normalOnMessage_ = ^(NSData* data){
184 | STMResponse* response = [weak(protocol_) parse:data];
185 |
186 | if (response.reqID == pushID) {
187 | weak(self).onpush(response.data);
188 | return;
189 | }
190 |
191 | Request* request = [weak(requests_) objectForKey:[NSNumber numberWithInt:response.reqID]];
192 | if (request == nil) {
193 | NSLog(@"error: not find request");
194 | return;
195 | }
196 | if (request.complete != nil) {
197 | request.complete();
198 | }
199 | if (response.status != STMResponseStatusSuccess
200 | && request.failed != nil) {
201 | if (response.data == nil) {
202 | request.failed(@"may be server error, but server has closed the error log");
203 | } else {
204 | request.failed([[NSString alloc] initWithData:response.data encoding:NSUTF8StringEncoding]);
205 | }
206 | }
207 | if (response.status == STMResponseStatusSuccess
208 | && request.suc != nil) {
209 | request.suc(response.data);
210 | }
211 |
212 | [weak(requests_) removeObjectForKey:[NSNumber numberWithInt:response.reqID]];
213 | };
214 |
215 | defineWEAK(onConnectionSuc_);
216 |
217 | net_.onopen = ^(){
218 | [weak(protocol_) onopen:^{
219 | [weak(self) sendAllRequests];
220 | }];
221 | if (weak(onConnectionSuc_) != nil) {
222 | weak(onConnectionSuc_)();
223 | }
224 | };
225 |
226 | defineWEAK(onConnectionFaild_);
227 |
228 | net_.onclose = ^(NSString* str){
229 | [weak(self) errorAllRequests:str];
230 |
231 | if (weak(onConnectionFaild_) != nil) {
232 | weak(onConnectionFaild_)(str);
233 | }
234 | };
235 |
236 | net_.onmessage = normalOnMessage_;
237 |
238 | [net_ open];
239 | }
240 |
241 | -(void)postMessage:(void(^)(void))message {
242 | STMClient* __weak _self = self;
243 | [[NSRunLoop currentRunLoop]performSelector:@selector(performMessageByRunLoop_:)
244 | target:_self
245 | argument:message
246 | order:0
247 | modes:@[[NSRunLoop currentRunLoop].currentMode]];
248 | }
249 |
250 | -(void)performMessageByRunLoop_:(id)message {
251 | void(^msg)(void) = message;
252 | msg();
253 | }
254 |
255 | -(void)sendAllRequests {
256 | defineWEAK(self);
257 |
258 | [requests_ enumerateKeysAndObjectsUsingBlock:^(NSNumber * _Nonnull key
259 | , Request * _Nonnull obj
260 | , BOOL * _Nonnull stop) {
261 | [weak(self) sendRequest:obj.body withHeader:obj.headers andReqID:obj.reqID];
262 | }];
263 | }
264 |
265 | -(void)setOnMessageToNormal {
266 | net_.onmessage = normalOnMessage_;
267 | }
268 |
269 | -(void)sendRequest:(NSData*)body
270 | withHeader:(NSDictionary*)header
271 | andReqID:(uint32_t)reqid {
272 |
273 | NSData* data = [protocol_ build:body
274 | withHeaders:header
275 | withReqID:reqid];
276 |
277 | if (data == nil) {
278 | [self postMessage:^{
279 | net_.onmessage([protocol_ buildFailedMessage:@"build message error, maybe length of headers' key or value > 255, or is not asscii"
280 | withReqid:reqid]);
281 | }];
282 | return;
283 | }
284 |
285 | [net_ send:data];
286 | }
287 |
288 | -(void)errorAllRequests:(NSString*)error {
289 | [requests_ enumerateKeysAndObjectsUsingBlock:^(NSNumber * _Nonnull key
290 | , Request * _Nonnull obj
291 | , BOOL * _Nonnull stop) {
292 | normalOnMessage_([protocol_ buildFailedMessage:error
293 | withReqid:[key intValue]]);
294 | }];
295 |
296 | [requests_ removeAllObjects];
297 | }
298 |
299 | @end
300 |
301 |
302 |
303 |
304 |
--------------------------------------------------------------------------------
/client/js/stm.client.js:
--------------------------------------------------------------------------------
1 | /**
2 | * Created by xpwu on 2016/12/1.
3 | */
4 |
5 |
6 | (function (ns) {
7 | "use strict";
8 |
9 | if (typeof StringView !== "function") {
10 | console.error("can not find StringView. this error maybe cause 'stm.Client is not a constructor'. you can find in https://developer.mozilla.org/en-US/Add-ons/Code_snippets/StringView or https://github.com/madmurphy/stringview.js");
11 | return;
12 | }
13 |
14 | function Request(body, onSuccess, headers, onFailed, onComplete, reqID) {
15 | /**
16 | *
17 | * @type {ArrayBuffer|string}
18 | */
19 | this.body = body || "";
20 | /**
21 | *
22 | * @type {Object}
23 | */
24 | this.headers = headers || {};
25 | /**
26 | *
27 | * @param {ArrayBuffer}data
28 | */
29 | this.onSuccess = onSuccess || function (data) {};
30 | /**
31 | *
32 | * @param {string} error
33 | */
34 | this.onFailed = onFailed || function (error) {};
35 | this.onComplete = onComplete || function () {};
36 | this.reqID = reqID;
37 | }
38 |
39 | var reqIDstart = 200;
40 | var pushID = 1; // need equal server
41 |
42 | function Client() {
43 | function init(client) {
44 | /**
45 | * @type {WebSocket}
46 | */
47 | client.net_ = null;
48 | client.netArgs_ = "";
49 | client.requests_ = Object.create(null);
50 | client.protocol_ = stm.ContentProtocol.extend(stm.DefaultContentProtocol);
51 | client.reqID_ = reqIDstart;
52 | client.onConnectionSuc_ = function () {};
53 | client.onConnectionFaild_ = function (error) {};
54 | client.normalOnMessage_ = function (data) {};
55 | client.connectTimeout_ = 30;
56 | }
57 | init(this);
58 |
59 | /**
60 | *
61 | * @param {ArrayBuffer}data
62 | */
63 | this.onPush = function (data) {};
64 | /**
65 | *
66 | * @var {function(Object)}
67 | */
68 | this.onPushJson = null;
69 | }
70 |
71 | function Private(obj) {
72 | return new PrivateWrapper(obj);
73 | }
74 |
75 | var pro = Client.prototype;
76 |
77 | /**
78 | *
79 | * @param {string}args ws(s)://xxxxx:xx
80 | * @param {function()|null}onSuccess
81 | * @param {function(string)|null}onFailed
82 | */
83 | pro.setConnectArgs = function(args, onSuccess, onFailed){
84 | this.netArgs_ = args;
85 | this.onConnectionFaild_ = onFailed || function (error) {};
86 | this.onConnectionSuc_ = onSuccess || function () {};
87 | };
88 |
89 | /**
90 | *
91 | * @param {number} connectTimeout unit: s
92 | */
93 | pro.setConfig = function (connectTimeout) {
94 | this.connectTimeout_ = connectTimeout;
95 | };
96 |
97 | /**
98 | *
99 | * @param {Object|null} [body]
100 | * @param {function(Object)|null} [onSuccess]
101 | * @param {Object|null} [headers]
102 | * @param {function(string)|null} [onFailed]
103 | * @param {function()|null} [onComplete]
104 | */
105 | pro.addJsonRequest = function (body, onSuccess, headers, onFailed, onComplete) {
106 | var callback = (onSuccess==null)?null:function (response) {
107 | onSuccess(JSON.parse(new StringView(response).toString()));
108 | };
109 |
110 | this.addRequest(JSON.stringify((body===null)?null:body)
111 | , callback, headers, onFailed, onComplete);
112 | };
113 |
114 | /**
115 | *
116 | * @param {ArrayBuffer|string|null} [body]
117 | * @param {function(ArrayBuffer)|null} [onSuccess]
118 | * @param {Object|null} [headers]
119 | * @param {function(string)|null} [onFailed]
120 | * @param {function()|null} [onComplete]
121 | */
122 | pro.addRequest = function (body, onSuccess, headers, onFailed, onComplete) {
123 | if (this.netArgs_ == null) {
124 | if (typeof onComplete === "function") {
125 | onComplete();
126 | }
127 | if (typeof onFailed === "function") {
128 | onFailed("net args not set");
129 | }
130 | return;
131 | }
132 |
133 | var reqid = Private(this).getReqID();
134 | this.requests_[reqid.toString()] = new Request(body, onSuccess, headers
135 | , onFailed, onComplete, reqid);
136 |
137 | if (this.net_ != null && this.net_.readyState == WebSocket.OPEN) {
138 | Private(this).sendRequest(this.requests_[reqid.toString()]);
139 | return;
140 | }
141 | if (this.net_ != null && this.net_.readyState == WebSocket.CONNECTING) {
142 | return;
143 | }
144 | Private(this).connect();
145 | };
146 |
147 | //-------------- private -------------
148 |
149 | function postTask(callback) {
150 | setTimeout(callback, 0);
151 | }
152 |
153 | /**
154 | *
155 | * @param {Client}client
156 | * @constructor
157 | */
158 | function PrivateWrapper(client) {
159 | /**
160 | *
161 | * @type {Client}
162 | * @private
163 | */
164 | this.client_ = client;
165 | }
166 |
167 | var privatePro = PrivateWrapper.prototype;
168 |
169 | /**
170 | *
171 | * @return {number|*}
172 | */
173 | privatePro.getReqID = function () {
174 | this.client_.reqID_++;
175 | if (this.client_.reqID_ < reqIDstart) {
176 | this.client_.reqID_ = reqIDstart;
177 | }
178 | return this.client_.reqID_;
179 | };
180 |
181 | /**
182 | *
183 | * @param {Request}request
184 | */
185 | privatePro.sendRequest = function (request) {
186 | var client = this.client_;
187 | var data = client.protocol_.build(request.body, request.headers, request.reqID);
188 |
189 | if (typeof data == "string") {
190 | postTask(function () {
191 | var error = client.protocol_.buildFailedMessage(data, request.reqID);
192 | client.net_.onmessage({data: error});
193 | });
194 | return;
195 | }
196 |
197 | client.net_.send(data);
198 | };
199 |
200 | privatePro.connect = function () {
201 | var client = this.client_;
202 | this.client_.normalOnMessage_ = function (data) {
203 |
204 | var response = client.protocol_.parse(data);
205 | if (response.reqID == pushID) {
206 | client.onPush(response.data);
207 |
208 | client.onPushJson
209 | && client.onPushJson(JSON.parse(new StringView(response.data).toString()));
210 | return;
211 | }
212 |
213 | var request = client.requests_[response.reqID.toString()];
214 | if (request == null) {
215 | console.error("not find request for reqID<"+response.reqID+">");
216 | return;
217 | }
218 |
219 | request.onComplete();
220 | if (response.state != stm.Response.State.Success) {
221 | if (response.data === null || response.data === undefined) {
222 | request.onFailed("may be server error, but server has closed the error log");
223 | } else {
224 | request.onFailed((new StringView(response.data)).toString());
225 | }
226 | } else {
227 | request.onSuccess(response.data);
228 | }
229 | delete client.requests_[response.reqID.toString()];
230 | };
231 |
232 | this.client_.net_ = new WebSocket(this.client_.netArgs_);
233 | client.net_.haserror = false; // 添加一项WebSocket没有的属性
234 | client.net_.binaryType = "arraybuffer";
235 | client.net_.onmessage = function (event) {
236 | client.normalOnMessage_(event.data);
237 | };
238 |
239 | var timer = setTimeout(function(){
240 | client.net_.timeout();
241 | }, client.connectTimeout_*1000);
242 |
243 | var that = this;
244 | client.net_.onopen = function(event){
245 | if (timer != null) {
246 | clearTimeout(timer);
247 | timer = null;
248 | }
249 |
250 | that.sendAllRequest();
251 | client.protocol_.onOpen(client.onConnectionSuc_);
252 | };
253 |
254 | client.net_.onclose = function(event) {
255 | if (timer != null) {
256 | clearTimeout(timer);
257 | timer = null;
258 | }
259 | // readyState 的状态改变会先于onclose的执行
260 | // if (client.net_.readyState != WebSocket.OPEN) {
261 | // return;
262 | // }
263 | client.net_.close(1000);
264 | client.protocol_.onClose();
265 | if (!client.net_.haserror) {
266 | client.net_.haserror = false;
267 | that.netError("connection closed by peer or connection error");
268 | }
269 | };
270 |
271 | client.net_.onerror = function(event) {
272 | // 部分错误可能会自动调用 onclose
273 | client.net_.haserror = true;
274 |
275 | if (timer != null) {
276 | clearTimeout(timer);
277 | timer = null;
278 | }
279 |
280 | that.netError("connect error---" + JSON.stringify(event));
281 | };
282 |
283 | client.net_.timeout = function(event) {
284 | timer = null;
285 | this.onopen = function(event){};
286 | this.onclose = function(event){};
287 | this.onerror = function(event){};
288 | this.onmessage = function(event){};
289 | client.net_ = null;
290 |
291 | that.netError("connect timeout");
292 | };
293 |
294 | };
295 |
296 | privatePro.sendAllRequest = function () {
297 | var client = this.client_;
298 | for (var req in client.requests_) {
299 | this.sendRequest(client.requests_[req]);
300 | }
301 | };
302 |
303 | privatePro.errorAllRequest = function (error) {
304 | var client = this.client_;
305 | for (var req in client.requests_) {
306 | (function (id) {
307 | postTask(function () {
308 | client.normalOnMessage_(client.protocol_.buildFailedMessage(error, id));
309 | });
310 | })(Number(req));
311 | }
312 | };
313 |
314 | privatePro.netError = function (errorstr) {
315 | var client = this.client_;
316 |
317 | this.errorAllRequest(errorstr);
318 |
319 | client.onConnectionFaild_(errorstr);
320 | };
321 |
322 | var stm = ns.stm = ns.stm || {};
323 | stm.Client = Client;
324 |
325 | })(this);
326 |
--------------------------------------------------------------------------------