{"action":"created","issue":{"url":"https://api.github.com/repos/cocos2d/cocos2d-x/issues/14867","repository_url":"https://api.github.com/repos/cocos2d/cocos2d-x","labels_url":"https://api.github.com/repos/cocos2d/cocos2d-x/issues/14867/labels{/name}","comments_url":"https://api.github.com/repos/cocos2d/cocos2d-x/issues/14867/comments","events_url":"https://api.github.com/repos/cocos2d/cocos2d-x/issues/14867/events","html_url":"https://github.com/cocos2d/cocos2d-x/pull/14867","id":125752245,"number":14867,"title":"WebSocket refactoring, bug fixes, improvements, and passes most Autobahn Test (The most standard WebSocket Protocol Test).","user":{"login":"dumganhar","id":493372,"avatar_url":"https://avatars.githubusercontent.com/u/493372?v=3","gravatar_id":"","url":"https://api.github.com/users/dumganhar","html_url":"https://github.com/dumganhar","followers_url":"https://api.github.com/users/dumganhar/followers","following_url":"https://api.github.com/users/dumganhar/following{/other_user}","gists_url":"https://api.github.com/users/dumganhar/gists{/gist_id}","starred_url":"https://api.github.com/users/dumganhar/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/dumganhar/subscriptions","organizations_url":"https://api.github.com/users/dumganhar/orgs","repos_url":"https://api.github.com/users/dumganhar/repos","events_url":"https://api.github.com/users/dumganhar/events{/privacy}","received_events_url":"https://api.github.com/users/dumganhar/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":{"login":"ricardoquesada","id":232330,"avatar_url":"https://avatars.githubusercontent.com/u/232330?v=3","gravatar_id":"","url":"https://api.github.com/users/ricardoquesada","html_url":"https://github.com/ricardoquesada","followers_url":"https://api.github.com/users/ricardoquesada/followers","following_url":"https://api.github.com/users/ricardoquesada/following{/other_user}","gists_url":"https://api.github.com/users/ricardoquesada/gists{/gist_id}","starred_url":"https://api.github.com/users/ricardoquesada/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/ricardoquesada/subscriptions","organizations_url":"https://api.github.com/users/ricardoquesada/orgs","repos_url":"https://api.github.com/users/ricardoquesada/repos","events_url":"https://api.github.com/users/ricardoquesada/events{/privacy}","received_events_url":"https://api.github.com/users/ricardoquesada/received_events","type":"User","site_admin":false},"milestone":null,"comments":19,"created_at":"2016-01-09T10:42:34Z","updated_at":"2016-02-14T02:46:07Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/cocos2d/cocos2d-x/pulls/14867","html_url":"https://github.com/cocos2d/cocos2d-x/pull/14867","diff_url":"https://github.com/cocos2d/cocos2d-x/pull/14867.diff","patch_url":"https://github.com/cocos2d/cocos2d-x/pull/14867.patch"},"body":"This PR is based on the latest release version of `libwebsockets`, so before merging it, please upgrade `libwebsockets`\r\n\r\n## Result\r\nIt has passed most of Autobahn Test (The most standard WebSocket Protocol Test).\r\nPlease see the result at http://182.254.241.97/runtime-test/websocket-report/index.html\r\n\r\n## Changes\r\n### Refactoring\r\n* Adds more callback functions like `onConnectionOpened`, `onConnectionClosed` rather than put all websocket callback in just one `onSocketCallback`, code will be clearer and readable.\r\n\r\n```c++\r\n    int onSocketCallback(struct lws *wsi, int reason, void *user, void *in, ssize_t len);\r\n\r\n    void onClientWritable();\r\n    void onClientReceivedData(void* in, ssize_t len);\r\n    void onConnectionOpened();\r\n    void onConnectionError();\r\n    void onConnectionClosed();\r\n```\r\n* Uses `performFunctionInCocosThread(cb);` to send msg to Cocos Thread rather than make a scheduler update\r\n* Uses `LOGD` for outputting log to debugging websocket connections since websocket stuff uses a sub thread. CCLOG isn't threadsafe.\r\n\r\n### Bug Fixes\r\n* WebSocket::close should not block Cocos Thread, it should just notify websocket thread to exit. Now the behavior is the same as Browser. To prove, you could type some test code in Chrome and the result will be:\r\n```javascript\r\nws = new WebSocket(\"ws://127.0.0.1:9123\"); ws.onclose = function(){ console.log(\"I'm closed\");}; \r\n(){ console.log(\"I'm closed\");}\r\nconsole.log(\"before close\"); ws.close(); console.log(\"hello\");\r\nVM437:2 before close\r\nVM437:2 hello\r\nundefined\r\nVM433:2 I'm closed\r\n```\r\n* Fixed every websocket event will cost 50ms at least, since the old way was wrong, we should not wait 50ms in sub thread while loop. `lws_service(xxx, time_to_wait)` will do it for us. So it fixed delay of message receive/send.\r\n* Fixed potential high CPU cost since the old code will trigger a websocket writable event every time after the writable callback. Now only when the size of the sending message queue isn't zero, a `lws_callback_on_writable ` will be invoked\r\n* Fixed `libwebsocket_context_destroy` may not be invoked while closing connection.\r\n* Fixed sending large data will trigger websocket errors\r\n* Fixed receiving large data in many frames will trigger JS `onmessage` callback many times\r\n* Fixed `lws_write` may return a smaller value than the value `n` for sending, a `WebSocketFrame` class is doing the job. `data->issued` should not be increased while a `WebSocketFrame` isn't totally sent.\r\n* Fixed connection isn't closed if received text message is an invalid UTF8 string.\r\n* Fixed the memory leak that JSB_WebSocketDelegate is never released.\r\n\r\n### Improvements\r\n* Better performance for received data buffer. Uses `std::vector` for dynamic received data buffer, the old way is every time there is a frame received, buffer memory will be extended every time there is a message comes. It was very low performance.\r\n* Supports receive/send data with zero size.\r\n* Larger socket rx/tx buffer size `WS_RX_BUFFER_SIZE` for better performance.\r\n* Adds static method `WebSocket::closeAllConnections`, it should be invoked while resetting `Director`, for ensure all websocket threads exit. Otherwise, cocos will release all engine classes when exiting game, then if a websocket event is coming, it will cause exception since websocket API is asynchronous.\r\n\r\n"},"comment":{"url":"https://api.github.com/repos/cocos2d/cocos2d-x/issues/comments/183805947","html_url":"https://github.com/cocos2d/cocos2d-x/pull/14867#issuecomment-183805947","issue_url":"https://api.github.com/repos/cocos2d/cocos2d-x/issues/14867","id":183805947,"user":{"login":"xiaofeng11","id":11676879,"avatar_url":"https://avatars.githubusercontent.com/u/11676879?v=3","gravatar_id":"","url":"https://api.github.com/users/xiaofeng11","html_url":"https://github.com/xiaofeng11","followers_url":"https://api.github.com/users/xiaofeng11/followers","following_url":"https://api.github.com/users/xiaofeng11/following{/other_user}","gists_url":"https://api.github.com/users/xiaofeng11/gists{/gist_id}","starred_url":"https://api.github.com/users/xiaofeng11/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/xiaofeng11/subscriptions","organizations_url":"https://api.github.com/users/xiaofeng11/orgs","repos_url":"https://api.github.com/users/xiaofeng11/repos","events_url":"https://api.github.com/users/xiaofeng11/events{/privacy}","received_events_url":"https://api.github.com/users/xiaofeng11/received_events","type":"User","site_admin":false},"created_at":"2016-02-14T02:46:07Z","updated_at":"2016-02-14T02:46:07Z","body":"@pandamicro @dumganhar Sorry, my mistake. New libwebsocket is compiled with openSSL support.\r\nBut I can not sure if Win10 & Win8.1 have same feature, because these lib can not compile with scripts. So I create project file from win32 src and modify code as patch in MS fork to compile these 2 lib"}}