├── .gitignore ├── LICENSE.txt ├── README.md ├── pom.xml └── src └── main └── java └── com └── sksamuel └── gwt ├── GwtWebsockets.gwt.xml └── websockets ├── Base64Utils.java ├── BinaryWebsocketListener.java ├── CloseEvent.java ├── Websocket.java ├── WebsocketListener.java └── WebsocketListenerExt.java /.gitignore: -------------------------------------------------------------------------------- 1 | /target 2 | /.classpath 3 | /.project 4 | /.settings 5 | /.idea 6 | *.iml 7 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | gwt-websockets 2 | ============== 3 | 4 | [](http://search.maven.org/#search%7Cga%7C1%7Ca%3A%22gwt-websockets%22) 5 | 6 | A simple GWT wrapper for javascript websockets which enable you to avoid writing native javascript code. This is not a fully featured client/server framework for websockets. Instead it is a simple wrapper for client side code when you need to connect to an existing websocket server. For example, this library was built because I needed to connect a mobile GWT webapp to a Java websocket system that used Apache Camel. 7 | 8 | This library has no dependancy outside of the standard GWT distribution. 9 | 10 | To use add this dependancy to your project (hosted on maven central): 11 | 12 | 13 | com.sksamuel.gwt 14 | gwt-websockets 15 | 1.0.4 16 | 17 | 18 | Then update your .gwt.xml files to include this: 19 | 20 | 21 | 22 | Getting Started 23 | =============== 24 | 25 | To create a websocket in your code, use 26 | 27 | `Websocket socket = new Websocket("ws://hostname:port/path");` 28 | 29 | Then attach one or more listeners which are used for the callbacks: 30 | 31 | socket.addListener(new WebsocketListener() { 32 | 33 | @Override 34 | public void onClose(CloseEvent event) { 35 | // do something on close 36 | } 37 | 38 | @Override 39 | public void onMessage(String msg) { 40 | // a message is received 41 | } 42 | 43 | @Override 44 | public void onOpen() { 45 | // do something on open 46 | } 47 | }); 48 | 49 | When the socket is successfully connected, the onOpen() callback will be invoked on each of your listeners. Similarly, for onClose() and onMessage(String). Note: You can add as many listeners as you want, and you can remove/add while the socket is open. 50 | 51 | To open a websocket use `socket.open();` 52 | 53 | To close a websocket `socket.close();` 54 | 55 | To send a message to the websocket server `socket.send("My message");` 56 | 57 | Sometimes you might want to check if websockets are available on your target system. For this you can use the static method `Websocket.isSupported()` which returns true if websockets are available. 58 | 59 | You can create as many websockets as you want on a single page. The library takes care of assigning each one to a different javascript global. 60 | 61 | Finally, you can get the status of the socket using the method `socket.getState()` which returns an integer for the 62 | current state of the socket, where `CONNECTING = 0, OPEN = 1, CLOSING = 2, CLOSED = 3`. 63 | 64 | Have fun. 65 | 66 | Binary support 67 | =============== 68 | 69 | Version 1.0.1 adds support for byte methods for sending and receiving. To send, simply use send(byte[]) method on Websocket. To receive, you must implement BinaryWebsocketListener instead of WebsocketListener and then you have a new callback method onMessage(byte[]). 70 | 71 | Because binary support on websockets isn't yet supported on all browsers, this modules sends binary data using base64. 72 | 73 | ## License 74 | ``` 75 | This software is licensed under the Apache 2 license, quoted below. 76 | 77 | Copyright 2013 Stephen Samuel 78 | 79 | Licensed under the Apache License, Version 2.0 (the "License"); you may not 80 | use this file except in compliance with the License. You may obtain a copy of 81 | the License at 82 | 83 | http://www.apache.org/licenses/LICENSE-2.0 84 | 85 | Unless required by applicable law or agreed to in writing, software 86 | distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 87 | WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 88 | License for the specific language governing permissions and limitations under 89 | the License. 90 | ``` 91 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 3 | 4.0.0 4 | 5 | 6 | org.sonatype.oss 7 | oss-parent 8 | 7 9 | 10 | 11 | com.sksamuel.gwt 12 | gwt-websockets 13 | 1.0.4 14 | 15 | gwt-websockets 16 | GWT Wrapper for browser Websockets 17 | https://github.com/sksamuel/gwt-websockets 18 | 19 | 20 | 21 | The Apache Software License, Version 2.0 22 | http://www.apache.org/licenses/LICENSE-2.0.txt 23 | repo 24 | 25 | 26 | 27 | 28 | scm:git:git@github.com:sksamuel/gwt-websockets.git 29 | scm:git:git@github.com:sksamuel/gwt-websockets.git 30 | it@github.com:sksamuel/gwt-websockets.git 31 | 32 | 33 | 34 | 35 | Stephen Samuel 36 | sam@sksamuel.com 37 | GMT 38 | 39 | 40 | 41 | 42 | 2.5 43 | 2.5.1 44 | 45 | 46 | 47 | 48 | com.google.gwt 49 | gwt-servlet 50 | ${gwt.version} 51 | provided 52 | 53 | 54 | com.google.gwt 55 | gwt-user 56 | ${gwt.version} 57 | provided 58 | 59 | 60 | 61 | 62 | 63 | release 64 | 65 | 66 | performRelease 67 | true 68 | 69 | 70 | 71 | 72 | 73 | org.apache.maven.plugins 74 | maven-gpg-plugin 75 | 1.1 76 | 77 | 78 | sign-artifacts 79 | verify 80 | 81 | sign 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | org.apache.maven.plugins 95 | maven-compiler-plugin 96 | 97 | 1.6 98 | 1.6 99 | 100 | 101 | 102 | org.apache.maven.plugins 103 | maven-resources-plugin 104 | ${maven.plugin.resources.version} 105 | 106 | UTF-8 107 | 108 | 109 | 110 | 111 | org.apache.maven.plugins 112 | maven-source-plugin 113 | 114 | 115 | attach-sources 116 | 117 | jar 118 | 119 | 120 | 121 | 122 | 123 | org.apache.maven.plugins 124 | maven-javadoc-plugin 125 | 126 | 127 | attach-javadocs 128 | 129 | jar 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | src/main/java 138 | 139 | 140 | src/main/resources 141 | 142 | **/*.java 143 | **/*.gwt.xml 144 | 145 | 146 | 147 | 148 | 149 | -------------------------------------------------------------------------------- /src/main/java/com/sksamuel/gwt/GwtWebsockets.gwt.xml: -------------------------------------------------------------------------------- 1 | 2 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /src/main/java/com/sksamuel/gwt/websockets/Base64Utils.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2009 Google Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | package com.sksamuel.gwt.websockets; 17 | 18 | /** 19 | * A utility to decode and encode byte arrays as Strings, using only "safe" 20 | * characters. 21 | */ 22 | public class Base64Utils { 23 | 24 | /** 25 | * An array mapping size but values to the characters that will be used to 26 | * represent them. Note that this is not identical to the set of characters 27 | * used by MIME-Base64. 28 | */ 29 | private static final char[] base64Chars = new char[] { 30 | 'A', 'B', 'C', 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', 'N', 31 | 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', 'X', 'Y', 'Z', 'a', 'b', 32 | 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', 'n', 'o', 'p', 33 | 'q', 'r', 's', 't', 'u', 'v', 'w', 'x', 'y', 'z', '0', '1', '2', '3', 34 | '4', '5', '6', '7', '8', '9', '$', '_'}; 35 | 36 | /** 37 | * An array mapping legal base 64 characters [a-zA-Z0-9$_] to their associated 38 | * 6-bit values. The source indices will be given by 7-bit ASCII characters, 39 | * thus the array size needs to be 128 (actually 123 would suffice for the 40 | * given set of characters in use). 41 | */ 42 | private static final byte[] base64Values = new byte[128]; 43 | 44 | /** 45 | * Initialize the base 64 encoder values. 46 | */ 47 | static { 48 | // Invert the mapping (i -> base64Chars[i]) 49 | for (int i = 0; i < base64Chars.length; i++) { 50 | base64Values[base64Chars[i]] = (byte) i; 51 | } 52 | } 53 | 54 | /** 55 | * Decode a base64 string into a byte array. 56 | * 57 | * @param data the encoded data. 58 | * @return a byte array. 59 | * @see #fromBase64(String) 60 | */ 61 | public static byte[] fromBase64(String data) { 62 | if (data == null) { 63 | return null; 64 | } 65 | 66 | int len = data.length(); 67 | assert (len % 4) == 0; 68 | 69 | if (len == 0) { 70 | return new byte[0]; 71 | } 72 | 73 | char[] chars = new char[len]; 74 | data.getChars(0, len, chars, 0); 75 | 76 | int olen = 3 * (len / 4); 77 | if (chars[len - 2] == '=') { 78 | --olen; 79 | } 80 | if (chars[len - 1] == '=') { 81 | --olen; 82 | } 83 | 84 | byte[] bytes = new byte[olen]; 85 | 86 | int iidx = 0; 87 | int oidx = 0; 88 | while (iidx < len) { 89 | int c0 = base64Values[chars[iidx++] & 0xff]; 90 | int c1 = base64Values[chars[iidx++] & 0xff]; 91 | int c2 = base64Values[chars[iidx++] & 0xff]; 92 | int c3 = base64Values[chars[iidx++] & 0xff]; 93 | int c24 = (c0 << 18) | (c1 << 12) | (c2 << 6) | c3; 94 | 95 | bytes[oidx++] = (byte) (c24 >> 16); 96 | if (oidx == olen) { 97 | break; 98 | } 99 | bytes[oidx++] = (byte) (c24 >> 8); 100 | if (oidx == olen) { 101 | break; 102 | } 103 | bytes[oidx++] = (byte) c24; 104 | } 105 | 106 | return bytes; 107 | } 108 | 109 | /** 110 | * Decode a base64 string into a long value. 111 | */ 112 | public static long longFromBase64(String value) { 113 | int pos = 0; 114 | long longVal = base64Values[value.charAt(pos++)]; 115 | int len = value.length(); 116 | while (pos < len) { 117 | longVal <<= 6; 118 | longVal |= base64Values[value.charAt(pos++)]; 119 | } 120 | return longVal; 121 | } 122 | 123 | /** 124 | * Converts a byte array into a base 64 encoded string. Null is encoded as 125 | * null, and an empty array is encoded as an empty string. Otherwise, the byte 126 | * data is read 3 bytes at a time, with bytes off the end of the array padded 127 | * with zeros. Each 24-bit chunk is encoded as 4 characters from the sequence 128 | * [A-Za-z0-9$_]. If one of the source positions consists entirely of padding 129 | * zeros, an '=' character is used instead. 130 | * 131 | * @param data a byte array, which may be null or empty 132 | * @return a String 133 | */ 134 | public static String toBase64(byte[] data) { 135 | if (data == null) { 136 | return null; 137 | } 138 | 139 | int len = data.length; 140 | if (len == 0) { 141 | return ""; 142 | } 143 | 144 | int olen = 4 * ((len + 2) / 3); 145 | char[] chars = new char[olen]; 146 | 147 | int iidx = 0; 148 | int oidx = 0; 149 | int charsLeft = len; 150 | while (charsLeft > 0) { 151 | int b0 = data[iidx++] & 0xff; 152 | int b1 = (charsLeft > 1) ? data[iidx++] & 0xff : 0; 153 | int b2 = (charsLeft > 2) ? data[iidx++] & 0xff : 0; 154 | int b24 = (b0 << 16) | (b1 << 8) | b2; 155 | 156 | int c0 = (b24 >> 18) & 0x3f; 157 | int c1 = (b24 >> 12) & 0x3f; 158 | int c2 = (b24 >> 6) & 0x3f; 159 | int c3 = b24 & 0x3f; 160 | 161 | chars[oidx++] = base64Chars[c0]; 162 | chars[oidx++] = base64Chars[c1]; 163 | chars[oidx++] = (charsLeft > 1) ? base64Chars[c2] : '='; 164 | chars[oidx++] = (charsLeft > 2) ? base64Chars[c3] : '='; 165 | 166 | charsLeft -= 3; 167 | } 168 | 169 | return new String(chars); 170 | } 171 | 172 | /** 173 | * Return a string containing a base-64 encoded version of the given long 174 | * value. Leading groups of all zero bits are omitted. 175 | */ 176 | public static String toBase64(long value) { 177 | // Convert to ints early to avoid need for long ops 178 | int low = (int) (value & 0xffffffff); 179 | int high = (int) (value >> 32); 180 | 181 | StringBuilder sb = new StringBuilder(); 182 | boolean haveNonZero = base64Append(sb, (high >> 28) & 0xf, false); 183 | haveNonZero = base64Append(sb, (high >> 22) & 0x3f, haveNonZero); 184 | haveNonZero = base64Append(sb, (high >> 16) & 0x3f, haveNonZero); 185 | haveNonZero = base64Append(sb, (high >> 10) & 0x3f, haveNonZero); 186 | haveNonZero = base64Append(sb, (high >> 4) & 0x3f, haveNonZero); 187 | int v = ((high & 0xf) << 2) | ((low >> 30) & 0x3); 188 | haveNonZero = base64Append(sb, v, haveNonZero); 189 | haveNonZero = base64Append(sb, (low >> 24) & 0x3f, haveNonZero); 190 | haveNonZero = base64Append(sb, (low >> 18) & 0x3f, haveNonZero); 191 | haveNonZero = base64Append(sb, (low >> 12) & 0x3f, haveNonZero); 192 | base64Append(sb, (low >> 6) & 0x3f, haveNonZero); 193 | base64Append(sb, low & 0x3f, true); 194 | 195 | return sb.toString(); 196 | } 197 | 198 | private static boolean base64Append(StringBuilder sb, int digit, 199 | boolean haveNonZero) { 200 | if (digit > 0) { 201 | haveNonZero = true; 202 | } 203 | if (haveNonZero) { 204 | sb.append(base64Chars[digit]); 205 | } 206 | return haveNonZero; 207 | } 208 | } 209 | -------------------------------------------------------------------------------- /src/main/java/com/sksamuel/gwt/websockets/BinaryWebsocketListener.java: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2013 Stephen Samuel 3 | 4 | Licensed under the Apache License,Version2.0(the"License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing,software 11 | distributed under the License is distributed on an"AS IS"BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | package com.sksamuel.gwt.websockets; 17 | 18 | 19 | /** 20 | * @author Stephen Samuel 21 | */ 22 | public interface BinaryWebsocketListener extends WebsocketListener { 23 | 24 | void onMessage(byte[] bytes); 25 | } 26 | -------------------------------------------------------------------------------- /src/main/java/com/sksamuel/gwt/websockets/CloseEvent.java: -------------------------------------------------------------------------------- 1 | package com.sksamuel.gwt.websockets; 2 | 3 | public class CloseEvent { 4 | 5 | private final short code; 6 | private final String reason; 7 | private final boolean wasClean; 8 | 9 | public CloseEvent(short code, String reason, boolean wasClean) { 10 | this.code = code; 11 | this.reason = reason; 12 | this.wasClean = wasClean; 13 | } 14 | 15 | public short code() { 16 | return code; 17 | } 18 | 19 | public String reason() { 20 | return reason; 21 | } 22 | 23 | public boolean wasClean() { 24 | return wasClean; 25 | } 26 | } -------------------------------------------------------------------------------- /src/main/java/com/sksamuel/gwt/websockets/Websocket.java: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2013 Stephen Samuel 3 | 4 | Licensed under the Apache License,Version2.0(the"License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing,software 11 | distributed under the License is distributed on an"AS IS"BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | package com.sksamuel.gwt.websockets; 17 | 18 | import java.util.HashSet; 19 | import java.util.Set; 20 | 21 | /** 22 | * @author Stephen K Samuel 14 Sep 2012 08:58:55 23 | */ 24 | public class Websocket { 25 | 26 | private static int counter = 1; 27 | 28 | private static native boolean _isWebsocket() /*-{ 29 | return ("WebSocket" in window); 30 | }-*/; 31 | 32 | public static boolean isSupported() { 33 | return _isWebsocket(); 34 | } 35 | 36 | private final Set listeners = new HashSet(); 37 | 38 | private final String varName; 39 | private final String url; 40 | 41 | public Websocket(String url) { 42 | this.url = url; 43 | this.varName = "gwtws-" + counter++; 44 | } 45 | 46 | private native void _close(String s) /*-{ 47 | $wnd[s].close(); 48 | }-*/; 49 | 50 | private native void _open(Websocket ws, String s, String url) /*-{ 51 | $wnd[s] = new WebSocket(url); 52 | $wnd[s].onopen = function() { ws.@com.sksamuel.gwt.websockets.Websocket::onOpen()(); }; 53 | $wnd[s].onclose = function(evt) { ws.@com.sksamuel.gwt.websockets.Websocket::onClose(SLjava/lang/String;Z)(evt.code, evt.reason, evt.wasClean); }; 54 | $wnd[s].onerror = function() { ws.@com.sksamuel.gwt.websockets.Websocket::onError()(); }; 55 | $wnd[s].onmessage = function(msg) { ws.@com.sksamuel.gwt.websockets.Websocket::onMessage(Ljava/lang/String;)(msg.data); } 56 | }-*/; 57 | 58 | private native void _send(String s, String msg) /*-{ 59 | $wnd[s].send(msg); 60 | }-*/; 61 | 62 | private native int _state(String s) /*-{ 63 | return $wnd[s].readyState; 64 | }-*/; 65 | 66 | public void addListener(WebsocketListener listener) { 67 | listeners.add(listener); 68 | } 69 | public void removeListener(WebsocketListener listener) { 70 | listeners.remove(listener); 71 | } 72 | 73 | public void close() { 74 | _close(varName); 75 | } 76 | 77 | public int getState() { 78 | return _state(varName); 79 | } 80 | 81 | protected void onClose(short code, String reason, boolean wasClean) { 82 | CloseEvent event = new CloseEvent(code, reason, wasClean); 83 | for (WebsocketListener listener : listeners) 84 | listener.onClose(event); 85 | } 86 | 87 | protected void onError() { 88 | for (WebsocketListener listener : listeners) { 89 | if (listener instanceof WebsocketListenerExt) { 90 | ((WebsocketListenerExt)listener).onError(); 91 | } 92 | } 93 | } 94 | 95 | protected void onMessage(String msg) { 96 | for (WebsocketListener listener : listeners) { 97 | listener.onMessage(msg); 98 | if (listener instanceof BinaryWebsocketListener) { 99 | byte[] bytes = Base64Utils.fromBase64(msg); 100 | ((BinaryWebsocketListener) listener).onMessage(bytes); 101 | } 102 | } 103 | } 104 | 105 | protected void onOpen() { 106 | for (WebsocketListener listener : listeners) 107 | listener.onOpen(); 108 | } 109 | 110 | public void open() { 111 | _open(this, varName, url); 112 | } 113 | 114 | public void send(String msg) { 115 | _send(varName, msg); 116 | } 117 | 118 | public void send(byte[] bytes) { 119 | String base64 = Base64Utils.toBase64(bytes); 120 | send(base64); 121 | } 122 | } -------------------------------------------------------------------------------- /src/main/java/com/sksamuel/gwt/websockets/WebsocketListener.java: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2013 Stephen Samuel 3 | 4 | Licensed under the Apache License,Version2.0(the"License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing,software 11 | distributed under the License is distributed on an"AS IS"BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | package com.sksamuel.gwt.websockets; 17 | 18 | /** 19 | * @author Stephen K Samuel 14 Sep 2012 08:58:10 20 | */ 21 | public interface WebsocketListener { 22 | 23 | void onClose(CloseEvent event); 24 | 25 | void onMessage(String msg); 26 | 27 | void onOpen(); 28 | } 29 | -------------------------------------------------------------------------------- /src/main/java/com/sksamuel/gwt/websockets/WebsocketListenerExt.java: -------------------------------------------------------------------------------- 1 | /** 2 | Copyright 2013 Stephen Samuel 3 | 4 | Licensed under the Apache License,Version2.0(the"License"); 5 | you may not use this file except in compliance with the License. 6 | You may obtain a copy of the License at 7 | 8 | http://www.apache.org/licenses/LICENSE-2.0 9 | 10 | Unless required by applicable law or agreed to in writing,software 11 | distributed under the License is distributed on an"AS IS"BASIS, 12 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,either express or implied. 13 | See the License for the specific language governing permissions and 14 | limitations under the License. 15 | */ 16 | package com.sksamuel.gwt.websockets; 17 | 18 | /** 19 | * @author Stephan Hesse 20 | */ 21 | public interface WebsocketListenerExt 22 | extends WebsocketListener { 23 | void onError(); 24 | } 25 | --------------------------------------------------------------------------------