{"action":"created","issue":{"url":"https://api.github.com/repos/boostorg/beast/issues/1209","repository_url":"https://api.github.com/repos/boostorg/beast","labels_url":"https://api.github.com/repos/boostorg/beast/issues/1209/labels{/name}","comments_url":"https://api.github.com/repos/boostorg/beast/issues/1209/comments","events_url":"https://api.github.com/repos/boostorg/beast/issues/1209/events","html_url":"https://github.com/boostorg/beast/issues/1209","id":344667996,"node_id":"MDU6SXNzdWUzNDQ2Njc5OTY=","number":1209,"title":"Getting \"existing connection forcibly closed by remote host\" when I should be getting websocket::error::closed","user":{"login":"emag37","id":28715405,"node_id":"MDQ6VXNlcjI4NzE1NDA1","avatar_url":"https://avatars3.githubusercontent.com/u/28715405?v=4","gravatar_id":"","url":"https://api.github.com/users/emag37","html_url":"https://github.com/emag37","followers_url":"https://api.github.com/users/emag37/followers","following_url":"https://api.github.com/users/emag37/following{/other_user}","gists_url":"https://api.github.com/users/emag37/gists{/gist_id}","starred_url":"https://api.github.com/users/emag37/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/emag37/subscriptions","organizations_url":"https://api.github.com/users/emag37/orgs","repos_url":"https://api.github.com/users/emag37/repos","events_url":"https://api.github.com/users/emag37/events{/privacy}","received_events_url":"https://api.github.com/users/emag37/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"assignees":[],"milestone":null,"comments":0,"created_at":"2018-07-26T02:04:56Z","updated_at":"2018-07-26T03:47:52Z","closed_at":null,"author_association":"NONE","body":"Hello,\r\n\r\nI have a simple test setup where I have a simple secure websocket server running in Tornado websockets in Python 2.7, and a C++ websocket client using the version of boost::beast included with the Boost 1.67.0 release. The connection is made over SSL with TLSv1.2. I'm compiling with MSVC 19.14.26433.0 x86_64 (32 bit compiler for 64 bit host) \r\n\r\nMy C++ client calls async_read and waits for data. When it receives data, it checks for any errors then fires a callback with said data. It then starts another async_read.\r\n\r\nFrom what I understand, when I call close() on the server-side websocket connection, the async_read callback on the C++ side should gracefully intercept and respond to the websocket 'close' frame, and callback with the error code set to websocket::error::closed. \r\n\r\nHowever, my async_read callback always seems to have \"An existing connection was forcibly closed by the remote host\" set as the error. I've also seen it as \"stream truncated\" a couple of times.\r\n\r\nI registered a control_callback, and am able to see the 'close' frame being received there, so I'm not sure why async_read does not have the correct error message.\r\n\r\nIs this a known issue? Am I doing something wrong? Thank you!"},"comment":{"url":"https://api.github.com/repos/boostorg/beast/issues/comments/407967619","html_url":"https://github.com/boostorg/beast/issues/1209#issuecomment-407967619","issue_url":"https://api.github.com/repos/boostorg/beast/issues/1209","id":407967619,"node_id":"MDEyOklzc3VlQ29tbWVudDQwNzk2NzYxOQ==","user":{"login":"vinniefalco","id":1503976,"node_id":"MDQ6VXNlcjE1MDM5NzY=","avatar_url":"https://avatars3.githubusercontent.com/u/1503976?v=4","gravatar_id":"","url":"https://api.github.com/users/vinniefalco","html_url":"https://github.com/vinniefalco","followers_url":"https://api.github.com/users/vinniefalco/followers","following_url":"https://api.github.com/users/vinniefalco/following{/other_user}","gists_url":"https://api.github.com/users/vinniefalco/gists{/gist_id}","starred_url":"https://api.github.com/users/vinniefalco/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/vinniefalco/subscriptions","organizations_url":"https://api.github.com/users/vinniefalco/orgs","repos_url":"https://api.github.com/users/vinniefalco/repos","events_url":"https://api.github.com/users/vinniefalco/events{/privacy}","received_events_url":"https://api.github.com/users/vinniefalco/received_events","type":"User","site_admin":false},"created_at":"2018-07-26T03:47:52Z","updated_at":"2018-07-26T03:47:52Z","author_association":"MEMBER","body":"> From what I understand, when I call close() on the server-side websocket connection, the async_read callback on the C++ side should gracefully intercept and respond to the websocket 'close' frame, and callback with the error code set to websocket::error::closed.\r\n\r\nYeah you have that all correct. `ECONNRESET` (\"An existing connection was forcibly closed by the remote host\") means exactly what it says. The remote host (Tornado websockets in this case) reset the connection.\r\n\r\nAnd if we look at the source code[1] for Tornado websockets we find this:\r\n```\r\n# Give the client a few seconds to complete a clean shutdown,\r\n# otherwise just close the connection.\r\nself._waiting = self.stream.io_loop.add_timeout(\r\n    self.stream.io_loop.time() + 5, self._abort)\r\n```\r\n\r\nHo ho! What's this? A call to `self_.abort()`? Not best practices :) Maybe on the Beast client side you are still writing data? Or for some other reason there is a delay? What happens when you don't use SSL?\r\n\r\n[1] http://www.tornadoweb.org/en/stable/_modules/tornado/websocket.html\r\n"}}
{"actor":{"display_login":"vinniefalco"}}