{"action":"created","issue":{"url":"https://api.github.com/repos/meebey/SmartIrc4net/issues/37","labels_url":"https://api.github.com/repos/meebey/SmartIrc4net/issues/37/labels{/name}","comments_url":"https://api.github.com/repos/meebey/SmartIrc4net/issues/37/comments","events_url":"https://api.github.com/repos/meebey/SmartIrc4net/issues/37/events","html_url":"https://github.com/meebey/SmartIrc4net/pull/37","id":96365062,"number":37,"title":"Transport abstraction, WebSocket support, bug fixes","user":{"login":"djkaty","id":4500319,"avatar_url":"https://avatars.githubusercontent.com/u/4500319?v=3","gravatar_id":"","url":"https://api.github.com/users/djkaty","html_url":"https://github.com/djkaty","followers_url":"https://api.github.com/users/djkaty/followers","following_url":"https://api.github.com/users/djkaty/following{/other_user}","gists_url":"https://api.github.com/users/djkaty/gists{/gist_id}","starred_url":"https://api.github.com/users/djkaty/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/djkaty/subscriptions","organizations_url":"https://api.github.com/users/djkaty/orgs","repos_url":"https://api.github.com/users/djkaty/repos","events_url":"https://api.github.com/users/djkaty/events{/privacy}","received_events_url":"https://api.github.com/users/djkaty/received_events","type":"User","site_admin":false},"labels":[],"state":"open","locked":false,"assignee":null,"milestone":null,"comments":15,"created_at":"2015-07-21T16:49:48Z","updated_at":"2015-07-25T17:57:13Z","closed_at":null,"pull_request":{"url":"https://api.github.com/repos/meebey/SmartIrc4net/pulls/37","html_url":"https://github.com/meebey/SmartIrc4net/pull/37","diff_url":"https://github.com/meebey/SmartIrc4net/pull/37.diff","patch_url":"https://github.com/meebey/SmartIrc4net/pull/37.patch"},"body":"This branch abstracts the TCP socket layer from IrcConnection and allows IrcConnection to use pluggable transports instead.\r\n\r\nTransports must implement the new IIrcTransportManager. Two transports are provided:\r\n\r\n- IrcTcpTransport, providing the same functionality as in the existing implementation\r\n- IrcWebSocketTransport, which allows IRC connections over a WebSocket\r\n\r\nThe read thread in IrcConnection is moved to IrcTcpTransport. IrcWebSocketTransport does not require a read thread as it is a wrapper around websocket-sharp which is event-driven.\r\n\r\nIIrcTransportManager specifies an event-driven receive handler OnMessageReceived which IrcConnection subscribes to. Therefore, the read thread in IrcConnection is replaced by a read queue. The OnMessageReceived handler in IrcConnection (Transport_OnMessageReceived) adds received messages to the read queue.\r\n\r\nAll transports support AutoRetry and AutoReconnect as these are managed in IrcConnection.\r\n\r\nNote that due to the way websocket-sharp is implemented, IrcWebSocketTransport supports AutoRetry but not a multiple server list.\r\n\r\nThe write buffers, WriteLine etc. are moved into WriteThread which is renamed WriteController to signify it also includes helper methods. This unifies all stream writes to all transports. When WriteController has written a line, it fires a new event OnWriteLine, which IrcConnection subscribes to. The event handler in IrcConnection fires its own OnWriteLine event to end-user applications.\r\n\r\nConnect() now supports passing an IIrcTransportManager as the only parameter - pre-populated with connection details - or a transport with a server list or port, plus the original Connect() overloads for backwards compatibility. These will use IrcTcpTransport by default, or whatever the current transport is if it has been changed previously.\r\n\r\nThe transport in use can be fetched via the new property IrcConnection.Transport. This can be used to modify the connection parameters before calling Connect().\r\n\r\nIn addition, numerous connection-related bugs are fixed:\r\n\r\n- If a new connection is made with a smaller server list, a potential IndexOutOfBoundsException bug is fixed\r\n- AutoRetry would never attempt more than once due to an incorrect comparison\r\n- The number of AutoRetry's is reset when starting a new connection. Before, less than the potential maximum could be attempted (if the comparison operator had been correct).\r\n- AutoRetry recursion has been changed to a do {...} while loop\r\n- The write thread would not reset its queues when reconnecting, meaning that existing queued data would attempt to be written to the new connection incorrectly\r\n- The read thread moved to IrcTcpTransport now cleanly closes the stream when stopping the thread rather than using the evil Thread.Abort().\r\n\r\nOther changes:\r\n\r\n- ProxyType.cs has been moved to the IrcTransport folder to reflect its proper use.\r\n\r\n- The read queue has been updated to use a generic collection Queue<string> instead of a .NET 1.0 non-type-safe collection.\r\n\r\n- DCC chat: IrcFeatures.Encoding no longer exists so DccChat.cs wouldn't compile. I have changed it to use the system default encoding (System.Text.Encoding.Default) so that it compiles.\r\n\r\nSyntax and testing:\r\n\r\nTest.cs has been updated to show all the new possible syntaxes for connecting using standard TCP or WebSockets, using an explicit or implicit transport instance. Please see this for usage details.\r\n\r\nI have added a /reconnect command in Test.cs to test reconnection scenarios.\r\n\r\nI have tested the library with all of the combinations in Test.cs and can confirm it works as expected. I cannot promise there are no threading bugs whatsoever, especially edge cases relating to disconnects, but I have simulated broken connections or failed connection starts to confirm it works at least superficially.\r\n\r\nBreaking changes:\r\n\r\nEncoding, UseSsl, ValidateServerCertificate, SslClientCertificate, SocketReceiveTimeout, SocketSendTimeout, ProxyHost, ProxyPort, ProxyType, ProxyUsername and ProxyPassword must now be set on IrcTcpTransport instead of IrcConnection. The property behaviour is otherwise the same (IrcWebSocketTransport uses websocket-sharp's semantics for setting SSL and proxy configurations).\r\n\r\n...\r\n\r\nGetting this + IRCv3 + Twitch support done is bubbling to the top of things I need to get done for my own project now so I hope we can sort this out quickly. Hope you like the changes!\r\n\r\nKaty.\r\n\r\n"},"comment":{"url":"https://api.github.com/repos/meebey/SmartIrc4net/issues/comments/124867300","html_url":"https://github.com/meebey/SmartIrc4net/pull/37#issuecomment-124867300","issue_url":"https://api.github.com/repos/meebey/SmartIrc4net/issues/37","id":124867300,"user":{"login":"djkaty","id":4500319,"avatar_url":"https://avatars.githubusercontent.com/u/4500319?v=3","gravatar_id":"","url":"https://api.github.com/users/djkaty","html_url":"https://github.com/djkaty","followers_url":"https://api.github.com/users/djkaty/followers","following_url":"https://api.github.com/users/djkaty/following{/other_user}","gists_url":"https://api.github.com/users/djkaty/gists{/gist_id}","starred_url":"https://api.github.com/users/djkaty/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/djkaty/subscriptions","organizations_url":"https://api.github.com/users/djkaty/orgs","repos_url":"https://api.github.com/users/djkaty/repos","events_url":"https://api.github.com/users/djkaty/events{/privacy}","received_events_url":"https://api.github.com/users/djkaty/received_events","type":"User","site_admin":false},"created_at":"2015-07-25T17:57:13Z","updated_at":"2015-07-25T17:57:13Z","body":"All requested changes made vis a vis my other comments above."}}