├── .gitignore ├── .idea ├── $PRODUCT_WORKSPACE_FILE$ ├── .gitignore ├── artifacts │ └── processing_websockets_jar.xml ├── misc.xml ├── modules.xml └── vcs.xml ├── LICENSE ├── README.md ├── examples ├── websocketClient │ └── websocketClient.pde └── websocketServer │ └── websocketServer.pde ├── library.properties ├── library ├── javax.servlet-api-3.1.0.jar ├── jetty-client-9.3.6.v20151106.jar ├── jetty-http-9.3.6.v20151106.jar ├── jetty-io-9.3.6.v20151106.jar ├── jetty-security-9.3.6.v20151106.jar ├── jetty-server-9.3.6.v20151106.jar ├── jetty-servlet-9.3.6.v20151106.jar ├── jetty-util-9.3.6.v20151106.jar ├── slf4j-api-1.7.13.jar ├── slf4j-simple-1.7.13.jar ├── webSockets.jar ├── websocket-api-9.3.6.v20151106.jar ├── websocket-client-9.3.6.v20151106.jar ├── websocket-common-9.3.6.v20151106.jar ├── websocket-server-9.3.6.v20151106.jar └── websocket-servlet-9.3.6.v20151106.jar ├── processing_websockets.iml ├── references ├── allclasses-frame.html ├── allclasses-noframe.html ├── constant-values.html ├── deprecated-list.html ├── help-doc.html ├── index-files │ ├── index-1.html │ ├── index-10.html │ ├── index-2.html │ ├── index-3.html │ ├── index-4.html │ ├── index-5.html │ ├── index-6.html │ ├── index-7.html │ ├── index-8.html │ └── index-9.html ├── index.html ├── overview-tree.html ├── package-list ├── script.js ├── stylesheet.css └── websockets │ ├── WebsocketClient.html │ ├── WebsocketClientEvents.html │ ├── WebsocketServer.html │ ├── WebsocketServerController.html │ ├── WebsocketServerCreator.html │ ├── WebsocketServerEvents.html │ ├── class-use │ ├── WebsocketClient.html │ ├── WebsocketClientEvents.html │ ├── WebsocketServer.html │ ├── WebsocketServerController.html │ ├── WebsocketServerCreator.html │ └── WebsocketServerEvents.html │ ├── package-frame.html │ ├── package-summary.html │ ├── package-tree.html │ └── package-use.html ├── src └── websockets │ ├── NoLogging.java │ ├── WebsocketClient.java │ ├── WebsocketClientEvents.java │ ├── WebsocketServer.java │ ├── WebsocketServerController.java │ ├── WebsocketServerCreator.java │ └── WebsocketServerEvents.java └── webSockets.zip /.gitignore: -------------------------------------------------------------------------------- 1 | .DS_Store 2 | 3 | # Created by https://www.gitignore.io/api/intellij 4 | # Edit at https://www.gitignore.io/?templates=intellij 5 | 6 | ### Intellij ### 7 | # Covers JetBrains IDEs: IntelliJ, RubyMine, PhpStorm, AppCode, PyCharm, CLion, Android Studio and WebStorm 8 | # Reference: https://intellij-support.jetbrains.com/hc/en-us/articles/206544839 9 | 10 | # User-specific stuff 11 | .idea/**/workspace.xml 12 | .idea/**/tasks.xml 13 | .idea/**/usage.statistics.xml 14 | .idea/**/dictionaries 15 | .idea/**/shelf 16 | 17 | # Generated files 18 | .idea/**/contentModel.xml 19 | 20 | # Sensitive or high-churn files 21 | .idea/**/dataSources/ 22 | .idea/**/dataSources.ids 23 | .idea/**/dataSources.local.xml 24 | .idea/**/sqlDataSources.xml 25 | .idea/**/dynamic.xml 26 | .idea/**/uiDesigner.xml 27 | .idea/**/dbnavigator.xml 28 | 29 | # Gradle 30 | .idea/**/gradle.xml 31 | .idea/**/libraries 32 | 33 | # Gradle and Maven with auto-import 34 | # When using Gradle or Maven with auto-import, you should exclude module files, 35 | # since they will be recreated, and may cause churn. Uncomment if using 36 | # auto-import. 37 | # .idea/modules.xml 38 | # .idea/*.iml 39 | # .idea/modules 40 | # *.iml 41 | # *.ipr 42 | 43 | # CMake 44 | cmake-build-*/ 45 | 46 | # Mongo Explorer plugin 47 | .idea/**/mongoSettings.xml 48 | 49 | # File-based project format 50 | *.iws 51 | 52 | # IntelliJ 53 | out/ 54 | 55 | # mpeltonen/sbt-idea plugin 56 | .idea_modules/ 57 | 58 | # JIRA plugin 59 | atlassian-ide-plugin.xml 60 | 61 | # Cursive Clojure plugin 62 | .idea/replstate.xml 63 | 64 | # Crashlytics plugin (for Android Studio and IntelliJ) 65 | com_crashlytics_export_strings.xml 66 | crashlytics.properties 67 | crashlytics-build.properties 68 | fabric.properties 69 | 70 | # Editor-based Rest Client 71 | .idea/httpRequests 72 | 73 | # Android studio 3.1+ serialized cache file 74 | .idea/caches/build_file_checksums.ser 75 | 76 | ### Intellij Patch ### 77 | # Comment Reason: https://github.com/joeblau/gitignore.io/issues/186#issuecomment-215987721 78 | 79 | # *.iml 80 | # modules.xml 81 | # .idea/misc.xml 82 | # *.ipr 83 | 84 | # Sonarlint plugin 85 | .idea/**/sonarlint/ 86 | 87 | # SonarQube Plugin 88 | .idea/**/sonarIssues.xml 89 | 90 | # Markdown Navigator plugin 91 | .idea/**/markdown-navigator.xml 92 | .idea/**/markdown-navigator/ 93 | 94 | # End of https://www.gitignore.io/api/intellij 95 | -------------------------------------------------------------------------------- /.idea/$PRODUCT_WORKSPACE_FILE$: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 1.8 8 | 9 | 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /.idea/.gitignore: -------------------------------------------------------------------------------- 1 | # Default ignored files 2 | /workspace.xml -------------------------------------------------------------------------------- /.idea/artifacts/processing_websockets_jar.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | $PROJECT_DIR$/out/artifacts/processing_websockets_jar 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/misc.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /.idea/modules.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | -------------------------------------------------------------------------------- /.idea/vcs.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2015 Alexandra Institute 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Websockets for Processing 2 | 3 | **Create websocket servers and clients, which makes it possible to communicate with the 4 | outside world including web sites. With this library it is possible to have true two-way 5 | real-time connections with other Processing sketches, web sites, Internet of Things 6 | devices, etc.** 7 | 8 | > 🙋 We are looking for a new maintainer / owner of this repository 9 | 10 | ## Download 11 | The library can be downloaded here: 12 | https://github.com/alexandrainst/processing_websockets/blob/master/webSockets.zip?raw=true 13 | 14 | ## Installation 15 | Unzip and put the extracted webSockets folder into the libraries folder of your Processing 16 | sketches. Reference and examples are included in the webSockets folder. 17 | 18 | ## Examples explained 19 | I have provided two simple examples on using both the client and server part. These can be 20 | found in the examples folder. Below I will go through each example, and elaborate their usage. 21 | 22 | ### Websocket client 23 | 24 | In the following I provide the full example code of creating a websocket client in Processing. 25 | In the below code I draw a new ellipse at a random location (without removing the previous) 26 | each time I get a message from the websocket server, and I send a message to the server every 27 | 5 seconds ("Client message"). 28 | 29 | ```java 30 | import websockets.*; 31 | 32 | WebsocketClient wsc; 33 | int now; 34 | boolean newEllipse; 35 | 36 | void setup(){ 37 | size(200,200); 38 | 39 | newEllipse=true; 40 | 41 | //Here I initiate the websocket connection by connecting to "ws://localhost:8025/john", which is the uri of the server. 42 | //this refers to the Processing sketch it self (you should always write "this"). 43 | wsc= new WebsocketClient(this, "ws://localhost:8025/john"); 44 | now=millis(); 45 | } 46 | 47 | void draw(){ 48 | //Here I draw a new ellipse if newEllipse is true 49 | if(newEllipse){ 50 | ellipse(random(width),random(height),10,10); 51 | newEllipse=false; 52 | } 53 | 54 | //Every 5 seconds I send a message to the server through the sendMessage method 55 | if(millis()>now+5000){ 56 | wsc.sendMessage("Client message"); 57 | now=millis(); 58 | } 59 | } 60 | 61 | //This is an event like onMouseClicked. If you chose to use it, it will be executed whenever the server sends a message 62 | void webSocketEvent(String msg){ 63 | println(msg); 64 | newEllipse=true; 65 | } 66 | ``` 67 | 68 | ### Websocket server 69 | 70 | In the following I provide the full example code of creating a websocket server in Processing. 71 | In the below code I move an ellipse to a random location when I get a message from a client, 72 | and I send a message to ll clients every 5 seconds ("Server message"). 73 | 74 | ```java 75 | import websockets.*; 76 | 77 | WebsocketServer ws; 78 | int now; 79 | float x,y; 80 | 81 | void setup(){ 82 | size(200,200); 83 | 84 | //Initiates the websocket server, and listens for incoming connections on ws://localhost:8025/john 85 | ws= new WebsocketServer(this,8025,"/john"); 86 | now=millis(); 87 | x=0; 88 | y=0; 89 | } 90 | 91 | void draw(){ 92 | background(0); 93 | ellipse(x,y,10,10); 94 | 95 | //Send message to all clients very 5 seconds 96 | if(millis()>now+5000){ 97 | ws.sendMessage("Server message"); 98 | now=millis(); 99 | } 100 | } 101 | 102 | //This is an event like onMouseClicked. If you chose to use it, it will be executed whenever a client sends a message 103 | void webSocketServerEvent(String msg){ 104 | println(msg); 105 | x=random(width); 106 | y=random(height); 107 | } 108 | ``` 109 | 110 | ### How to set custom headers on your client 111 | 112 | Construct your `WebsocketClient` with custom headers passing them as a `StringArray`, with `key:value` pairs separated by colons: 113 | 114 | ```java 115 | StringList headers = new StringList(); 116 | headers.append("User-Agent:Processing"); 117 | wsc=new WebsocketClient(this, "ws://simple-websocket-server-echo.glitch.me/", headers); 118 | ``` 119 | 120 | 121 | ### Set message max size 122 | 123 | Call this method before calling the constructor to specify the message max size in bytes 124 | 125 | WebsocketServer.setMaxMessageSize(200000); 126 | 127 | ### Enable logging 128 | 129 | By default logging has been disabled, as it looks like errors in the 130 | Processing IDE's console. Call this method before calling the constructor 131 | 132 | WebsocketServer.enableDebug(); 133 | 134 | ### How to be notified of user connections / disconnections 135 | 136 | Implement the following two methods, which will receive the user id hash and 137 | the user IP address. 138 | 139 | ```java 140 | public void webSocketConnectEvent(String uid, String ip) { 141 | println("Someone connected", uid, ip); 142 | } 143 | 144 | public void webSocketDisconnectEvent(String uid, String ip) { 145 | println("Someone disconnected", uid, ip); 146 | } 147 | ``` 148 | 149 | ### How to send a message to a specific user 150 | 151 | You need the user ID to send a message to that user only. 152 | You receive that user ID when the user first connects. 153 | 154 | ws.sendMessageTo("message", "userID"); 155 | 156 | or 157 | 158 | ws.sendMessageTo(byteArray, "userID"); 159 | 160 | ### How to instantiate the WebsocketServer in your own class instead of the PApplet 161 | 162 | Note the extra second argument in the constructor. That's the Object that will implement all the webSocketXXX() methods. Without that second argument it is assumed that the PApplet will implement such methods. 163 | 164 | ```java 165 | public class CaptainSocket { 166 | WebsocketServer ws; 167 | CaptainSocket(PApplet p5) { 168 | ws = new WebsocketServer(p5, this, 8025, "/miau"); 169 | } 170 | public void webSocketServerEvent(String msg) { 171 | println(msg); 172 | } 173 | } 174 | 175 | ... in your PApplet ... 176 | 177 | CaptainSocket socket; 178 | void setup() { 179 | socket = new CaptainSocket(this); 180 | } 181 | 182 | ``` 183 | 184 | ## Technical development details 185 | 186 | The library has been developed on a Mac with El Capitan, I have used the Eclipse Luna IDE, 187 | and I have only tested on Processing version 3.0.1. 188 | 189 | The library is build with the Jetty websocket implementation, and different Jetty libraries 190 | are therefore needed for running this library. All dependencies are included in the downloadable 191 | zip file. The source code is available through this Github project (open source under MIT 192 | license) as well as included in the zip file below. 193 | -------------------------------------------------------------------------------- /examples/websocketClient/websocketClient.pde: -------------------------------------------------------------------------------- 1 | import websockets.*; 2 | 3 | WebsocketClient wsc; 4 | int now; 5 | boolean newEllipse; 6 | 7 | void setup(){ 8 | size(200,200); 9 | 10 | newEllipse=true; 11 | 12 | wsc= new WebsocketClient(this, "ws://localhost:8025/john"); 13 | now=millis(); 14 | } 15 | 16 | void draw(){ 17 | if(newEllipse){ 18 | ellipse(random(width),random(height),10,10); 19 | newEllipse=false; 20 | } 21 | 22 | if(millis()>now+5000){ 23 | wsc.sendMessage("Client message"); 24 | now=millis(); 25 | } 26 | } 27 | 28 | void webSocketEvent(String msg){ 29 | println(msg); 30 | newEllipse=true; 31 | } -------------------------------------------------------------------------------- /examples/websocketServer/websocketServer.pde: -------------------------------------------------------------------------------- 1 | import websockets.*; 2 | 3 | WebsocketServer ws; 4 | int now; 5 | float x,y; 6 | 7 | void setup(){ 8 | size(200,200); 9 | ws= new WebsocketServer(this,8025,"/john"); 10 | now=millis(); 11 | x=0; 12 | y=0; 13 | } 14 | 15 | void draw(){ 16 | background(0); 17 | ellipse(x,y,10,10); 18 | if(millis()>now+5000){ 19 | ws.sendMessage("Server message"); 20 | now=millis(); 21 | } 22 | } 23 | 24 | void webSocketServerEvent(String msg){ 25 | println(msg); 26 | x=random(width); 27 | y=random(height); 28 | } -------------------------------------------------------------------------------- /library.properties: -------------------------------------------------------------------------------- 1 | # UTF-8 supported. 2 | 3 | # The name of your library as you want it formatted. 4 | name = Websockets 5 | 6 | # List of authors. Links can be provided using the syntax [author name](url). 7 | authors = Lasse Steenbock Vestergaard 8 | 9 | # A web page for your library, NOT a direct link to where to download it. 10 | url = https://github.com/alexandrainst/processing_websockets 11 | 12 | # The category (or categories) of your library, must be from the following list: 13 | # "3D" "Animation" "Compilations" "Data" 14 | # "Fabrication" "Geometry" "GUI" "Hardware" 15 | # "I/O" "Language" "Math" "Simulation" 16 | # "Sound" "Utilities" "Typography" "Video & Vision" 17 | # 18 | # If a value other than those listed is used, your library will listed as 19 | # "Other". Many categories must be comma-separated. 20 | categories = Data, I/O 21 | 22 | # A short sentence (or fragment) to summarize the library's function. This will 23 | # be shown from inside the PDE when the library is being installed. Avoid 24 | # repeating the name of your library here. Also, avoid saying anything redundant 25 | # like mentioning that it's a library. This should start with a capitalized 26 | # letter, and end with a period. 27 | sentence = Create websocket servers and clients, which makes it possible to communicate with the outside world including web sites. 28 | 29 | # Additional information suitable for the Processing website. The value of 30 | # 'sentence' always will be prepended, so you should start by writing the 31 | # second sentence here. If your library only works on certain operating systems, 32 | # mention it here. 33 | paragraph = With this library it's possible to have true two way real-time connections with other Processing sketches, web sites, Internet of Things devises etc. For a concrete use case please take a look at the examples folder. 34 | 35 | # Links in the 'sentence' and 'paragraph' attributes can be inserted using the 36 | # same syntax as for authors. 37 | # That is, [here is a link to Processing](http://processing.org/) 38 | 39 | # A version number that increments once with each release. This is used to 40 | # compare different versions of the same library, and check if an update is 41 | # available. You should think of it as a counter, counting the total number of 42 | # releases you've had. 43 | version = 1 # This must be parsable as an int 44 | 45 | # The version as the user will see it. If blank, the version attribute will be 46 | # used here. This should be a single word, with no spaces. 47 | prettyVersion = 0.1b # This is treated as a String 48 | 49 | # The min and max revision of Processing compatible with your library. 50 | # Note that these fields use the revision and not the version of Processing, 51 | # parsable as an int. For example, the revision number for 2.2.1 is 227. 52 | # You can find the revision numbers in the change log: 53 | # https://raw.githubusercontent.com/processing/processing/master/build/shared/revisions.txt 54 | # Only use maxRevision (or minRevision), when your library is known to 55 | # break in a later (or earlier) release. Otherwise, use the default value 0. 56 | minRevision = 0 57 | maxRevision = 0 -------------------------------------------------------------------------------- /library/javax.servlet-api-3.1.0.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandrainst/processing_websockets/ceec7cf5cd3e07b8a3fb5552f291e363ae10e27c/library/javax.servlet-api-3.1.0.jar -------------------------------------------------------------------------------- /library/jetty-client-9.3.6.v20151106.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandrainst/processing_websockets/ceec7cf5cd3e07b8a3fb5552f291e363ae10e27c/library/jetty-client-9.3.6.v20151106.jar -------------------------------------------------------------------------------- /library/jetty-http-9.3.6.v20151106.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandrainst/processing_websockets/ceec7cf5cd3e07b8a3fb5552f291e363ae10e27c/library/jetty-http-9.3.6.v20151106.jar -------------------------------------------------------------------------------- /library/jetty-io-9.3.6.v20151106.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandrainst/processing_websockets/ceec7cf5cd3e07b8a3fb5552f291e363ae10e27c/library/jetty-io-9.3.6.v20151106.jar -------------------------------------------------------------------------------- /library/jetty-security-9.3.6.v20151106.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandrainst/processing_websockets/ceec7cf5cd3e07b8a3fb5552f291e363ae10e27c/library/jetty-security-9.3.6.v20151106.jar -------------------------------------------------------------------------------- /library/jetty-server-9.3.6.v20151106.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandrainst/processing_websockets/ceec7cf5cd3e07b8a3fb5552f291e363ae10e27c/library/jetty-server-9.3.6.v20151106.jar -------------------------------------------------------------------------------- /library/jetty-servlet-9.3.6.v20151106.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandrainst/processing_websockets/ceec7cf5cd3e07b8a3fb5552f291e363ae10e27c/library/jetty-servlet-9.3.6.v20151106.jar -------------------------------------------------------------------------------- /library/jetty-util-9.3.6.v20151106.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandrainst/processing_websockets/ceec7cf5cd3e07b8a3fb5552f291e363ae10e27c/library/jetty-util-9.3.6.v20151106.jar -------------------------------------------------------------------------------- /library/slf4j-api-1.7.13.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandrainst/processing_websockets/ceec7cf5cd3e07b8a3fb5552f291e363ae10e27c/library/slf4j-api-1.7.13.jar -------------------------------------------------------------------------------- /library/slf4j-simple-1.7.13.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandrainst/processing_websockets/ceec7cf5cd3e07b8a3fb5552f291e363ae10e27c/library/slf4j-simple-1.7.13.jar -------------------------------------------------------------------------------- /library/webSockets.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandrainst/processing_websockets/ceec7cf5cd3e07b8a3fb5552f291e363ae10e27c/library/webSockets.jar -------------------------------------------------------------------------------- /library/websocket-api-9.3.6.v20151106.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandrainst/processing_websockets/ceec7cf5cd3e07b8a3fb5552f291e363ae10e27c/library/websocket-api-9.3.6.v20151106.jar -------------------------------------------------------------------------------- /library/websocket-client-9.3.6.v20151106.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandrainst/processing_websockets/ceec7cf5cd3e07b8a3fb5552f291e363ae10e27c/library/websocket-client-9.3.6.v20151106.jar -------------------------------------------------------------------------------- /library/websocket-common-9.3.6.v20151106.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandrainst/processing_websockets/ceec7cf5cd3e07b8a3fb5552f291e363ae10e27c/library/websocket-common-9.3.6.v20151106.jar -------------------------------------------------------------------------------- /library/websocket-server-9.3.6.v20151106.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandrainst/processing_websockets/ceec7cf5cd3e07b8a3fb5552f291e363ae10e27c/library/websocket-server-9.3.6.v20151106.jar -------------------------------------------------------------------------------- /library/websocket-servlet-9.3.6.v20151106.jar: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandrainst/processing_websockets/ceec7cf5cd3e07b8a3fb5552f291e363ae10e27c/library/websocket-servlet-9.3.6.v20151106.jar -------------------------------------------------------------------------------- /processing_websockets.iml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | -------------------------------------------------------------------------------- /references/allclasses-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | All Classes 7 | 8 | 9 | 10 | 11 | 12 |

All Classes

13 |
14 | 22 |
23 | 24 | 25 | -------------------------------------------------------------------------------- /references/allclasses-noframe.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | All Classes 7 | 8 | 9 | 10 | 11 | 12 |

All Classes

13 |
14 | 22 |
23 | 24 | 25 | -------------------------------------------------------------------------------- /references/constant-values.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Constant Field Values 7 | 8 | 9 | 10 | 11 | 12 | 22 | 25 | 26 |
27 | 28 | 29 |
Skip navigation links
30 | 31 | 32 | 33 | 42 |
43 | 70 | 71 |
72 |

Constant Field Values

73 |

Contents

74 |
75 | 76 |
77 | 78 | 79 |
Skip navigation links
80 | 81 | 82 | 83 | 92 |
93 | 120 | 121 | 122 | 123 | -------------------------------------------------------------------------------- /references/deprecated-list.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Deprecated List 7 | 8 | 9 | 10 | 11 | 12 | 22 | 25 | 26 |
27 | 28 | 29 |
Skip navigation links
30 | 31 | 32 | 33 | 42 |
43 | 70 | 71 |
72 |

Deprecated API

73 |

Contents

74 |
75 | 76 |
77 | 78 | 79 |
Skip navigation links
80 | 81 | 82 | 83 | 92 |
93 | 120 | 121 | 122 | 123 | -------------------------------------------------------------------------------- /references/help-doc.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | API Help 7 | 8 | 9 | 10 | 11 | 12 | 22 | 25 | 26 |
27 | 28 | 29 |
Skip navigation links
30 | 31 | 32 | 33 | 42 |
43 | 70 | 71 |
72 |

How This API Document Is Organized

73 |
This API (Application Programming Interface) document has pages corresponding to the items in the navigation bar, described as follows.
74 |
75 |
76 | 175 | This help file applies to API documentation generated using the standard doclet.
176 | 177 |
178 | 179 | 180 |
Skip navigation links
181 | 182 | 183 | 184 | 193 |
194 | 221 | 222 | 223 | 224 | -------------------------------------------------------------------------------- /references/index-files/index-1.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | C-Index 7 | 8 | 9 | 10 | 11 | 12 | 22 | 25 | 26 |
27 | 28 | 29 |
Skip navigation links
30 | 31 | 32 | 33 | 42 |
43 | 70 | 71 |
C D F G H J O R S W  72 | 73 | 74 |

C

75 |
76 |
createWebSocket(ServletUpgradeRequest, ServletUpgradeResponse) - Method in class websockets.WebsocketServerCreator
77 |
 
78 |
ctrl - Variable in class websockets.WebsocketServerEvents
79 |
 
80 |
81 | C D F G H J O R S W 
82 | 83 |
84 | 85 | 86 |
Skip navigation links
87 | 88 | 89 | 90 | 99 |
100 | 127 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /references/index-files/index-10.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | W-Index 7 | 8 | 9 | 10 | 11 | 12 | 22 | 25 | 26 |
27 | 28 | 29 |
Skip navigation links
30 | 31 | 32 | 33 | 42 |
43 | 70 | 71 |
C D F G H J O R S W  72 | 73 | 74 |

W

75 |
76 |
WebsocketClient - Class in websockets
77 |
 
78 |
WebsocketClient(PApplet, String) - Constructor for class websockets.WebsocketClient
79 |
80 |
Initiating the client connection
81 |
82 |
WebsocketClientEvents - Class in websockets
83 |
 
84 |
WebsocketClientEvents(PApplet, Method) - Constructor for class websockets.WebsocketClientEvents
85 |
 
86 |
websockets - package websockets
87 |
 
88 |
WebsocketServer - Class in websockets
89 |
 
90 |
WebsocketServer(PApplet, int, String) - Constructor for class websockets.WebsocketServer
91 |
92 |
The websocket server object that is initiated directly in the Processing sketch
93 |
94 |
WebsocketServerController - Class in websockets
95 |
 
96 |
WebsocketServerController(PApplet, Method) - Constructor for class websockets.WebsocketServerController
97 |
98 |
Initiates the communication management between websocket events and the Processing sketch
99 |
100 |
WebsocketServerCreator - Class in websockets
101 |
 
102 |
WebsocketServerCreator(WebsocketServerController) - Constructor for class websockets.WebsocketServerCreator
103 |
 
104 |
WebsocketServerEvents - Class in websockets
105 |
 
106 |
WebsocketServerEvents(WebsocketServerController) - Constructor for class websockets.WebsocketServerEvents
107 |
 
108 |
writeAllMembers(String) - Method in class websockets.WebsocketServerController
109 |
110 |
Writes a message to all active clients
111 |
112 |
writeSpecificMember(String, String) - Method in class websockets.WebsocketServerController
113 |
114 |
This method is not yet fully implemented, and therefore not working!
115 |
116 |
117 | C D F G H J O R S W 
118 | 119 |
120 | 121 | 122 |
Skip navigation links
123 | 124 | 125 | 126 | 135 |
136 | 163 | 164 | 165 | 166 | -------------------------------------------------------------------------------- /references/index-files/index-2.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | D-Index 7 | 8 | 9 | 10 | 11 | 12 | 22 | 25 | 26 |
27 | 28 | 29 |
Skip navigation links
30 | 31 | 32 | 33 | 42 |
43 | 70 | 71 |
C D F G H J O R S W  72 | 73 | 74 |

D

75 |
76 |
dispose() - Method in class websockets.WebsocketClient
77 |
 
78 |
dispose() - Method in class websockets.WebsocketServer
79 |
 
80 |
81 | C D F G H J O R S W 
82 | 83 |
84 | 85 | 86 |
Skip navigation links
87 | 88 | 89 | 90 | 99 |
100 | 127 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /references/index-files/index-3.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | F-Index 7 | 8 | 9 | 10 | 11 | 12 | 22 | 25 | 26 |
27 | 28 | 29 |
Skip navigation links
30 | 31 | 32 | 33 | 42 |
43 | 70 | 71 |
C D F G H J O R S W  72 | 73 | 74 |

F

75 |
76 |
findMemberByName(String) - Method in class websockets.WebsocketServerController
77 |
78 |
Find specific client connection from a name.
79 |
80 |
81 | C D F G H J O R S W 
82 | 83 |
84 | 85 | 86 |
Skip navigation links
87 | 88 | 89 | 90 | 99 |
100 | 127 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /references/index-files/index-4.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | G-Index 7 | 8 | 9 | 10 | 11 | 12 | 22 | 25 | 26 |
27 | 28 | 29 |
Skip navigation links
30 | 31 | 32 | 33 | 42 |
43 | 70 | 71 |
C D F G H J O R S W  72 | 73 | 74 |

G

75 |
76 |
getLatch() - Method in class websockets.WebsocketClientEvents
77 |
 
78 |
79 | C D F G H J O R S W 
80 | 81 |
82 | 83 | 84 |
Skip navigation links
85 | 86 | 87 | 88 | 97 |
98 | 125 | 126 | 127 | 128 | -------------------------------------------------------------------------------- /references/index-files/index-5.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | H-Index 7 | 8 | 9 | 10 | 11 | 12 | 22 | 25 | 26 |
27 | 28 | 29 |
Skip navigation links
30 | 31 | 32 | 33 | 42 |
43 | 70 | 71 |
C D F G H J O R S W  72 | 73 | 74 |

H

75 |
76 |
handleClose(int, String) - Method in class websockets.WebsocketServerEvents
77 |
78 |
Handles closing down a specific client connection, and removes the client from the list of clients
79 |
80 |
handleConnect(Session) - Method in class websockets.WebsocketServerEvents
81 |
82 |
Handles new client connections, and adding the client to a list of clients, so that we can send messages to it later
83 |
84 |
handleError(Throwable) - Method in class websockets.WebsocketServerEvents
85 |
86 |
Handling connection errors and writes the to the console
87 |
88 |
handleMessage(String) - Method in class websockets.WebsocketServerEvents
89 |
90 |
Handles incoming messages, and passes them on to the Processing sketch's websocket event method
91 |
92 |
93 | C D F G H J O R S W 
94 | 95 |
96 | 97 | 98 |
Skip navigation links
99 | 100 | 101 | 102 | 111 |
112 | 139 | 140 | 141 | 142 | -------------------------------------------------------------------------------- /references/index-files/index-6.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | J-Index 7 | 8 | 9 | 10 | 11 | 12 | 22 | 25 | 26 |
27 | 28 | 29 |
Skip navigation links
30 | 31 | 32 | 33 | 42 |
43 | 70 | 71 |
C D F G H J O R S W  72 | 73 | 74 |

J

75 |
76 |
join(WebsocketServerEvents) - Method in class websockets.WebsocketServerController
77 |
78 |
Add new client to the list of all active clients
79 |
80 |
81 | C D F G H J O R S W 
82 | 83 |
84 | 85 | 86 |
Skip navigation links
87 | 88 | 89 | 90 | 99 |
100 | 127 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /references/index-files/index-7.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | O-Index 7 | 8 | 9 | 10 | 11 | 12 | 22 | 25 | 26 |
27 | 28 | 29 |
Skip navigation links
30 | 31 | 32 | 33 | 42 |
43 | 70 | 71 |
C D F G H J O R S W  72 | 73 | 74 |

O

75 |
76 |
onConnect(Session) - Method in class websockets.WebsocketClientEvents
77 |
78 |
Handling establishment of the connection
79 |
80 |
onError(Throwable) - Method in class websockets.WebsocketClientEvents
81 |
82 |
Handles errors occurring and writing them to the console
83 |
84 |
onText(Session, String) - Method in class websockets.WebsocketClientEvents
85 |
86 |
Sending incoming messages to the Processing sketch's websocket event function
87 |
88 |
89 | C D F G H J O R S W 
90 | 91 |
92 | 93 | 94 |
Skip navigation links
95 | 96 | 97 | 98 | 107 |
108 | 135 | 136 | 137 | 138 | -------------------------------------------------------------------------------- /references/index-files/index-8.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | R-Index 7 | 8 | 9 | 10 | 11 | 12 | 22 | 25 | 26 |
27 | 28 | 29 |
Skip navigation links
30 | 31 | 32 | 33 | 42 |
43 | 70 | 71 |
C D F G H J O R S W  72 | 73 | 74 |

R

75 |
76 |
remove(WebsocketServerEvents) - Method in class websockets.WebsocketServerController
77 |
78 |
Removes client to the list of all active clients
79 |
80 |
81 | C D F G H J O R S W 
82 | 83 |
84 | 85 | 86 |
Skip navigation links
87 | 88 | 89 | 90 | 99 |
100 | 127 | 128 | 129 | 130 | -------------------------------------------------------------------------------- /references/index-files/index-9.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | S-Index 7 | 8 | 9 | 10 | 11 | 12 | 22 | 25 | 26 |
27 | 28 | 29 |
Skip navigation links
30 | 31 | 32 | 33 | 42 |
43 | 70 | 71 |
C D F G H J O R S W  72 | 73 | 74 |

S

75 |
76 |
sendMessage(String) - Method in class websockets.WebsocketClient
77 |
78 |
Send message to the websocket server.
79 |
80 |
sendMessage(String) - Method in class websockets.WebsocketClientEvents
81 |
82 |
Sends message to the websocket server
83 |
84 |
sendMessage(String) - Method in class websockets.WebsocketServer
85 |
86 |
This method is used for sending messages to all connected clients.
87 |
88 |
sendToOnMessageListener(String) - Method in class websockets.WebsocketServerController
89 |
90 |
Sends incoming message directly to the Processing sketch's websocket event function
91 |
92 |
session - Variable in class websockets.WebsocketServerEvents
93 |
 
94 |
95 | C D F G H J O R S W 
96 | 97 |
98 | 99 | 100 |
Skip navigation links
101 | 102 | 103 | 104 | 113 |
114 | 141 | 142 | 143 | 144 | -------------------------------------------------------------------------------- /references/index.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Generated Documentation (Untitled) 7 | 59 | 60 | 61 | 62 | 63 | 64 | <noscript> 65 | <div>JavaScript is disabled on your browser.</div> 66 | </noscript> 67 | <h2>Frame Alert</h2> 68 | <p>This document is designed to be viewed using the frames feature. If you see this message, you are using a non-frame-capable web client. Link to <a href="websockets/package-summary.html">Non-frame version</a>.</p> 69 | 70 | 71 | 72 | -------------------------------------------------------------------------------- /references/overview-tree.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Class Hierarchy 7 | 8 | 9 | 10 | 11 | 12 | 22 | 25 | 26 |
27 | 28 | 29 |
Skip navigation links
30 | 31 | 32 | 33 | 42 |
43 | 70 | 71 |
72 |

Hierarchy For All Packages

73 | Package Hierarchies: 74 | 77 |
78 |
79 |

Class Hierarchy

80 | 92 |
93 | 94 |
95 | 96 | 97 |
Skip navigation links
98 | 99 | 100 | 101 | 110 |
111 | 138 | 139 | 140 | 141 | -------------------------------------------------------------------------------- /references/package-list: -------------------------------------------------------------------------------- 1 | websockets 2 | -------------------------------------------------------------------------------- /references/script.js: -------------------------------------------------------------------------------- 1 | function show(type) 2 | { 3 | count = 0; 4 | for (var key in methods) { 5 | var row = document.getElementById(key); 6 | if ((methods[key] & type) != 0) { 7 | row.style.display = ''; 8 | row.className = (count++ % 2) ? rowColor : altColor; 9 | } 10 | else 11 | row.style.display = 'none'; 12 | } 13 | updateTabs(type); 14 | } 15 | 16 | function updateTabs(type) 17 | { 18 | for (var value in tabs) { 19 | var sNode = document.getElementById(tabs[value][0]); 20 | var spanNode = sNode.firstChild; 21 | if (value == type) { 22 | sNode.className = activeTableTab; 23 | spanNode.innerHTML = tabs[value][1]; 24 | } 25 | else { 26 | sNode.className = tableTab; 27 | spanNode.innerHTML = "" + tabs[value][1] + ""; 28 | } 29 | } 30 | } 31 | -------------------------------------------------------------------------------- /references/websockets/WebsocketClient.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | WebsocketClient 7 | 8 | 9 | 10 | 11 | 12 | 28 | 31 | 32 |
33 | 34 | 35 |
Skip navigation links
36 | 37 | 38 | 39 | 48 |
49 | 91 | 92 | 93 |
94 |
websockets
95 |

Class WebsocketClient

96 |
97 |
98 | 106 |
107 | 121 |
122 |
123 | 179 |
180 |
181 | 240 |
241 |
242 | 243 | 244 |
245 | 246 | 247 |
Skip navigation links
248 | 249 | 250 | 251 | 260 |
261 | 303 | 304 | 305 | 306 | -------------------------------------------------------------------------------- /references/websockets/WebsocketServer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | WebsocketServer 7 | 8 | 9 | 10 | 11 | 12 | 28 | 31 | 32 |
33 | 34 | 35 |
Skip navigation links
36 | 37 | 38 | 39 | 48 |
49 | 91 | 92 | 93 |
94 |
websockets
95 |

Class WebsocketServer

96 |
97 |
98 | 106 |
107 | 119 |
120 |
121 | 178 |
179 |
180 | 241 |
242 |
243 | 244 | 245 |
246 | 247 | 248 |
Skip navigation links
249 | 250 | 251 | 252 | 261 |
262 | 304 | 305 | 306 | 307 | -------------------------------------------------------------------------------- /references/websockets/WebsocketServerCreator.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | WebsocketServerCreator 7 | 8 | 9 | 10 | 11 | 12 | 28 | 31 | 32 |
33 | 34 | 35 |
Skip navigation links
36 | 37 | 38 | 39 | 48 |
49 | 91 | 92 | 93 |
94 |
websockets
95 |

Class WebsocketServerCreator

96 |
97 |
98 | 106 |
107 | 126 |
127 |
128 | 176 |
177 |
178 | 221 |
222 |
223 | 224 | 225 |
226 | 227 | 228 |
Skip navigation links
229 | 230 | 231 | 232 | 241 |
242 | 284 | 285 | 286 | 287 | -------------------------------------------------------------------------------- /references/websockets/class-use/WebsocketClient.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Uses of Class websockets.WebsocketClient 7 | 8 | 9 | 10 | 11 | 12 | 22 | 25 | 26 |
27 | 28 | 29 |
Skip navigation links
30 | 31 | 32 | 33 | 42 |
43 | 70 | 71 |
72 |

Uses of Class
websockets.WebsocketClient

73 |
74 |
No usage of websockets.WebsocketClient
75 | 76 |
77 | 78 | 79 |
Skip navigation links
80 | 81 | 82 | 83 | 92 |
93 | 120 | 121 | 122 | 123 | -------------------------------------------------------------------------------- /references/websockets/class-use/WebsocketClientEvents.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Uses of Class websockets.WebsocketClientEvents 7 | 8 | 9 | 10 | 11 | 12 | 22 | 25 | 26 |
27 | 28 | 29 |
Skip navigation links
30 | 31 | 32 | 33 | 42 |
43 | 70 | 71 |
72 |

Uses of Class
websockets.WebsocketClientEvents

73 |
74 |
No usage of websockets.WebsocketClientEvents
75 | 76 |
77 | 78 | 79 |
Skip navigation links
80 | 81 | 82 | 83 | 92 |
93 | 120 | 121 | 122 | 123 | -------------------------------------------------------------------------------- /references/websockets/class-use/WebsocketServer.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Uses of Class websockets.WebsocketServer 7 | 8 | 9 | 10 | 11 | 12 | 22 | 25 | 26 |
27 | 28 | 29 |
Skip navigation links
30 | 31 | 32 | 33 | 42 |
43 | 70 | 71 |
72 |

Uses of Class
websockets.WebsocketServer

73 |
74 |
No usage of websockets.WebsocketServer
75 | 76 |
77 | 78 | 79 |
Skip navigation links
80 | 81 | 82 | 83 | 92 |
93 | 120 | 121 | 122 | 123 | -------------------------------------------------------------------------------- /references/websockets/class-use/WebsocketServerController.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Uses of Class websockets.WebsocketServerController 7 | 8 | 9 | 10 | 11 | 12 | 22 | 25 | 26 |
27 | 28 | 29 |
Skip navigation links
30 | 31 | 32 | 33 | 42 |
43 | 70 | 71 |
72 |

Uses of Class
websockets.WebsocketServerController

73 |
74 |
75 | 113 |
114 | 115 |
116 | 117 | 118 |
Skip navigation links
119 | 120 | 121 | 122 | 131 |
132 | 159 | 160 | 161 | 162 | -------------------------------------------------------------------------------- /references/websockets/class-use/WebsocketServerCreator.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Uses of Class websockets.WebsocketServerCreator 7 | 8 | 9 | 10 | 11 | 12 | 22 | 25 | 26 |
27 | 28 | 29 |
Skip navigation links
30 | 31 | 32 | 33 | 42 |
43 | 70 | 71 |
72 |

Uses of Class
websockets.WebsocketServerCreator

73 |
74 |
No usage of websockets.WebsocketServerCreator
75 | 76 |
77 | 78 | 79 |
Skip navigation links
80 | 81 | 82 | 83 | 92 |
93 | 120 | 121 | 122 | 123 | -------------------------------------------------------------------------------- /references/websockets/class-use/WebsocketServerEvents.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Uses of Class websockets.WebsocketServerEvents 7 | 8 | 9 | 10 | 11 | 12 | 22 | 25 | 26 |
27 | 28 | 29 |
Skip navigation links
30 | 31 | 32 | 33 | 42 |
43 | 70 | 71 |
72 |

Uses of Class
websockets.WebsocketServerEvents

73 |
74 |
75 | 122 |
123 | 124 |
125 | 126 | 127 |
Skip navigation links
128 | 129 | 130 | 131 | 140 |
141 | 168 | 169 | 170 | 171 | -------------------------------------------------------------------------------- /references/websockets/package-frame.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | websockets 7 | 8 | 9 | 10 | 11 | 12 |

websockets

13 |
14 |

Classes

15 | 23 |
24 | 25 | 26 | -------------------------------------------------------------------------------- /references/websockets/package-summary.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | websockets 7 | 8 | 9 | 10 | 11 | 12 | 22 | 25 | 26 |
27 | 28 | 29 |
Skip navigation links
30 | 31 | 32 | 33 | 42 |
43 | 70 | 71 |
72 |

Package websockets

73 |
74 |
75 | 112 |
113 | 114 |
115 | 116 | 117 |
Skip navigation links
118 | 119 | 120 | 121 | 130 |
131 | 158 | 159 | 160 | 161 | -------------------------------------------------------------------------------- /references/websockets/package-tree.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | websockets Class Hierarchy 7 | 8 | 9 | 10 | 11 | 12 | 22 | 25 | 26 |
27 | 28 | 29 |
Skip navigation links
30 | 31 | 32 | 33 | 42 |
43 | 70 | 71 |
72 |

Hierarchy For Package websockets

73 |
74 |
75 |

Class Hierarchy

76 | 88 |
89 | 90 |
91 | 92 | 93 |
Skip navigation links
94 | 95 | 96 | 97 | 106 |
107 | 134 | 135 | 136 | 137 | -------------------------------------------------------------------------------- /references/websockets/package-use.html: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | Uses of Package websockets 7 | 8 | 9 | 10 | 11 | 12 | 22 | 25 | 26 |
27 | 28 | 29 |
Skip navigation links
30 | 31 | 32 | 33 | 42 |
43 | 70 | 71 |
72 |

Uses of Package
websockets

73 |
74 |
75 | 95 |
96 | 97 |
98 | 99 | 100 |
Skip navigation links
101 | 102 | 103 | 104 | 113 |
114 | 141 | 142 | 143 | 144 | -------------------------------------------------------------------------------- /src/websockets/NoLogging.java: -------------------------------------------------------------------------------- 1 | package websockets; 2 | 3 | import org.eclipse.jetty.util.log.Logger; 4 | 5 | /** 6 | * @author Abe Pazos 7 | * 8 | * A silent logger for Jetty. Used to mute Jetty and avoid excessive 9 | * INFO messages in the Processing IDE's console. 10 | */ 11 | 12 | public class NoLogging implements Logger { 13 | @Override public String getName() { return "no"; } 14 | @Override public void warn(String msg, Object... args) { } 15 | @Override public void warn(Throwable thrown) { } 16 | @Override public void warn(String msg, Throwable thrown) { } 17 | @Override public void info(String msg, Object... args) { } 18 | @Override public void info(Throwable thrown) { } 19 | @Override public void info(String msg, Throwable thrown) { } 20 | @Override public boolean isDebugEnabled() { return false; } 21 | @Override public void setDebugEnabled(boolean enabled) { } 22 | @Override public void debug(String msg, Object... args) { } 23 | @Override public void debug(String s, long l) { } 24 | @Override public void debug(Throwable thrown) { } 25 | @Override public void debug(String msg, Throwable thrown) { } 26 | @Override public Logger getLogger(String name) { return this; } 27 | @Override public void ignore(Throwable ignored) { } 28 | } -------------------------------------------------------------------------------- /src/websockets/WebsocketClient.java: -------------------------------------------------------------------------------- 1 | package websockets; 2 | 3 | import java.lang.reflect.Method; 4 | import java.net.URI; 5 | import org.eclipse.jetty.client.HttpClient; 6 | import org.eclipse.jetty.util.ssl.SslContextFactory; 7 | import org.eclipse.jetty.websocket.client.ClientUpgradeRequest; 8 | import org.eclipse.jetty.websocket.client.WebSocketClient; 9 | import processing.core.PApplet; 10 | 11 | /** 12 | * 13 | * @author Lasse Steenbock Vestergaard 14 | * 15 | * Class for creating websocket client connections to any websocket server. Sub-protocols have not yet been implemented, and it's therefore only possible to connect to regular websocket servers. 16 | * 17 | */ 18 | public class WebsocketClient { 19 | private Method webSocketEvent; 20 | private Method webSocketEventBinary; 21 | private WebsocketClientEvents socket; 22 | 23 | /** 24 | * 25 | * Initiating the client connection 26 | * 27 | * @param parent Processing's PApplet object 28 | * @param endpointURI The URI to connect to Ex. ws://localhost:8025/john 29 | */ 30 | public WebsocketClient(PApplet parent, String endpointURI) { 31 | this(parent, parent, endpointURI, new StringList()); 32 | } 33 | 34 | /** 35 | * 36 | * Initiating the client connection 37 | * 38 | * @param parent Processing's PApplet object 39 | * @param endpointURI The URI to connect to Ex. ws://localhost:8025/john 40 | * @param headers A list of custom headers to attach to the WS request, like "User-Agent:Processing" 41 | */ 42 | public WebsocketClient(PApplet parent, String endpointURI, StringList headers) { 43 | this(parent, parent, endpointURI, headers); 44 | } 45 | 46 | /** 47 | * More flexible constructor in case you don't want callbacks called 48 | * in your PApplet but in a different class. Use this if you are 49 | * instantiating WebsocketClient in a class. 50 | * 51 | * @param parent Processing's PApplet object 52 | * @param callbacks The object implementing .webSocketEvent() 53 | * @param endpointURI The URI to connect to Ex. ws://localhost:8025/john 54 | * @param headers A list of custom headers to attach to the WS request, like "User-Agent:Processing" 55 | */ 56 | public WebsocketClient(PApplet parent, Object callbacks, 57 | String endpointURI, StringList headers) { 58 | parent.registerMethod("dispose", this); 59 | 60 | try { 61 | webSocketEvent = callbacks.getClass().getMethod("webSocketEvent", 62 | String.class); 63 | webSocketEventBinary = callbacks.getClass().getMethod("webSocketEvent", byte[].class, int.class, int.class); 64 | } catch (Exception e) { 65 | // no such method, or an error.. which is fine, just ignore 66 | } 67 | 68 | WebSocketClient client = null; 69 | 70 | if(endpointURI.startsWith("wss")) { 71 | SslContextFactory ssl = new SslContextFactory(); 72 | client = new WebSocketClient(ssl); 73 | } else { 74 | client = new WebSocketClient(); 75 | } 76 | 77 | try { 78 | socket = new WebsocketClientEvents(callbacks, webSocketEvent, 79 | webSocketEventBinary); 80 | client.start(); 81 | URI echoUri = new URI(endpointURI); 82 | ClientUpgradeRequest request = new ClientUpgradeRequest(); 83 | 84 | // If headers are present, set them 85 | for (String header : headers) 86 | { 87 | String[] h = header.split(":"); 88 | if (h.length != 2) 89 | { 90 | throw new Exception("Incorrectly formatted header \"" + header + 91 | "\", please use \":\" to separate key and value, " + 92 | "as in \"User-Agent:Processing\""); 93 | } 94 | request.setHeader(h[0], h[1]); 95 | } 96 | 97 | client.connect(socket, echoUri, request); 98 | socket.getLatch().await(); 99 | 100 | } catch (Throwable t) { 101 | t.printStackTrace(); 102 | } 103 | } 104 | 105 | /** 106 | * 107 | * Send message to the websocket server. At a later stage it should be possible to send messages to specific clients connected to the same server 108 | * 109 | * @param message The message to send 110 | */ 111 | public void sendMessage(String message){ 112 | socket.sendMessage(message); 113 | } 114 | 115 | public void sendMessage(byte[] data){ 116 | socket.sendMessage(data); 117 | } 118 | 119 | public void dispose(){ 120 | // Anything in here will be called automatically when 121 | // the parent sketch shuts down. For instance, this might 122 | // shut down a thread used by this library. 123 | } 124 | } 125 | -------------------------------------------------------------------------------- /src/websockets/WebsocketClientEvents.java: -------------------------------------------------------------------------------- 1 | package websockets; 2 | 3 | import java.io.IOException; 4 | import java.lang.reflect.Method; 5 | import java.util.concurrent.CountDownLatch; 6 | import java.nio.ByteBuffer; 7 | 8 | import org.eclipse.jetty.websocket.api.Session; 9 | import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect; 10 | import org.eclipse.jetty.websocket.api.annotations.OnWebSocketError; 11 | import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage; 12 | import org.eclipse.jetty.websocket.api.annotations.WebSocket; 13 | 14 | /** 15 | * 16 | * @author Lasse Steenbock Vestergaard 17 | * 18 | * Class responsible for handling all websocket events 19 | * 20 | */ 21 | @WebSocket 22 | public class WebsocketClientEvents { 23 | private Session session; 24 | CountDownLatch latch = new CountDownLatch(1); 25 | private Object parent; 26 | private Method onMessageEvent; 27 | private Method onMessageEventBinary; 28 | 29 | public WebsocketClientEvents(Object p, Method event, Method eventBinary) { 30 | parent = p; 31 | onMessageEvent = event; 32 | onMessageEventBinary = eventBinary; 33 | } 34 | 35 | /** 36 | * 37 | * Sending incoming messages to the Processing sketch's websocket event function 38 | * 39 | * @param session The connection between server and client 40 | * @param message The received message 41 | * @throws IOException If no event fonction is registered in the Processing sketch then an exception is thrown, but it will be ignored 42 | */ 43 | @OnWebSocketMessage 44 | public void onText(Session session, String message) throws IOException { 45 | if (onMessageEvent != null) { 46 | try { 47 | onMessageEvent.invoke(parent, message); 48 | } catch (Exception e) { 49 | System.err 50 | .println("Disabling webSocketEvent() because of an error."); 51 | e.printStackTrace(); 52 | onMessageEvent = null; 53 | } 54 | } 55 | } 56 | 57 | @OnWebSocketMessage 58 | public void onBinary(Session session, byte[] buf, int offset, int length) throws IOException { 59 | if (onMessageEventBinary != null) { 60 | try { 61 | onMessageEventBinary.invoke(parent, buf, offset, length); 62 | } catch (Exception e) { 63 | System.err 64 | .println("Disabling webSocketEvent() because of an error."); 65 | e.printStackTrace(); 66 | onMessageEventBinary = null; 67 | } 68 | } 69 | } 70 | 71 | /** 72 | * 73 | * Handling establishment of the connection 74 | * 75 | * @param session The connection between server and client 76 | */ 77 | @OnWebSocketConnect 78 | public void onConnect(Session session) { 79 | this.session = session; 80 | latch.countDown(); 81 | } 82 | 83 | /** 84 | * 85 | * Sends message to the websocket server 86 | * 87 | * @param str The message to send to the server 88 | */ 89 | public void sendMessage(String str) { 90 | try { 91 | session.getRemote().sendString(str); 92 | } catch (IOException e) { 93 | e.printStackTrace(); 94 | } 95 | } 96 | 97 | public void sendMessage(byte[] data) { 98 | try { 99 | ByteBuffer buf = ByteBuffer.wrap(data); 100 | session.getRemote().sendBytes(buf); 101 | } catch (IOException e) { 102 | e.printStackTrace(); 103 | } 104 | } 105 | 106 | /** 107 | * 108 | * Handles errors occurring and writing them to the console 109 | * 110 | * @param cause The cause of an error 111 | */ 112 | @OnWebSocketError 113 | public void onError(Throwable cause) { 114 | System.out.printf("onError(%s: %s)%n",cause.getClass().getSimpleName(), cause.getMessage()); 115 | cause.printStackTrace(System.out); 116 | } 117 | 118 | public CountDownLatch getLatch() { 119 | return latch; 120 | } 121 | } 122 | -------------------------------------------------------------------------------- /src/websockets/WebsocketServer.java: -------------------------------------------------------------------------------- 1 | package websockets; 2 | 3 | import org.eclipse.jetty.server.Server; 4 | import org.eclipse.jetty.server.handler.ContextHandler; 5 | import org.eclipse.jetty.websocket.server.WebSocketHandler; 6 | import org.eclipse.jetty.websocket.servlet.WebSocketServletFactory; 7 | 8 | import processing.core.PApplet; 9 | 10 | /** 11 | * 12 | * @author Lasse Steenbock Vestergaard 13 | * @author Abe Pazos (changes) 14 | * 15 | */ 16 | public class WebsocketServer { 17 | private WebsocketServerController serverController; 18 | private Server server; 19 | 20 | private static int MAX_MSG_SIZE = 65536; 21 | private static boolean DEBUG = false; 22 | 23 | /** 24 | * 25 | * The websocket server object that is initiated directly in the Processing sketch 26 | * 27 | * @param parent Processing's PApplet object 28 | * @param port The port number you want the websocket server to initiate its connection on 29 | * @param uri The uri you want your server to respond to. Ex. /john (if the port is set to ex. 8025, then the full URI would be ws://localhost:8025/john). 30 | */ 31 | public WebsocketServer(PApplet parent, int port, String uri){ 32 | this(parent, parent, port, uri); 33 | } 34 | 35 | /** 36 | * 37 | * @param parent Processing's PApplet object 38 | * @param listenerObject The object implementing .webSocketServerEvent() 39 | * @param port The port number you want the websocket server to initiate its connection on 40 | * @param uri The uri you want your server to respond to. Ex. /john (if the port is set to ex. 8025, then the full URI would be ws://localhost:8025/john). 41 | */ 42 | public WebsocketServer(PApplet parent, Object listenerObject, int port, 43 | String uri) { 44 | 45 | parent.registerMethod("dispose", this); 46 | 47 | // Logging is disabled by default because it looks like errors 48 | // in the Processing IDE (five red INFO messages on start) 49 | if(!DEBUG) { 50 | org.eclipse.jetty.util.log.Log.setLog(new NoLogging()); 51 | } 52 | 53 | server = new Server(port); 54 | serverController = new WebsocketServerController(listenerObject); 55 | 56 | WebSocketHandler wsHandler = new WebSocketHandler() { 57 | 58 | @Override 59 | public void configure(WebSocketServletFactory factory){ 60 | // Set max message sizes. Set by calling the static 61 | // method setMaxMessageSize(bytes) before the constructor. 62 | factory.getPolicy().setMaxTextMessageSize(MAX_MSG_SIZE); 63 | factory.getPolicy().setMaxBinaryMessageSize(MAX_MSG_SIZE); 64 | 65 | factory.setCreator(new WebsocketServerCreator(serverController)); 66 | } 67 | }; 68 | 69 | ContextHandler contextHandler = new ContextHandler(uri); 70 | contextHandler.setAllowNullPathInfo(true); // disable redirect from /ws to /ws/ 71 | contextHandler.setHandler(wsHandler); 72 | 73 | server.setHandler(contextHandler); 74 | 75 | try { 76 | server.start(); 77 | } catch (Exception e) { 78 | e.printStackTrace(); 79 | } 80 | } 81 | 82 | /** 83 | * 84 | * Send String message to all connected clients 85 | * 86 | * @param message The message content as a String 87 | */ 88 | public void sendMessage(String message) { 89 | serverController.writeAllMembers(message); 90 | } 91 | 92 | /** 93 | * 94 | * Send byte[] message to all connected clients 95 | * 96 | * @param data The message content as a byte[] 97 | */ 98 | public void sendMessage(byte[] data) { 99 | serverController.writeAllMembers(data); 100 | } 101 | 102 | /** 103 | * 104 | * Send String message to one receiver 105 | * 106 | * @param message The message content as a String 107 | * @param to Receiver userId of this message 108 | */ 109 | public void sendMessageTo(String message, String to) { 110 | serverController.writeSpecificMember(message, to); 111 | } 112 | 113 | /** 114 | * 115 | * Send byte[] message to one receiver 116 | * 117 | * @param data The message content as a byte[] 118 | * @param to Receiver userId of this message 119 | */ 120 | public void sendMessageTo(byte[] data, String to) { 121 | serverController.writeSpecificMember(data, to); 122 | } 123 | 124 | /** 125 | * Set the max message size in bytes, 64Kb by default 126 | * @param bytes 127 | */ 128 | public static void setMaxMessageSize(int bytes) { 129 | MAX_MSG_SIZE = bytes; 130 | } 131 | 132 | /** 133 | * Enable logging, disabled by default because it looks like errors 134 | * in the Processing IDE 135 | */ 136 | public static void enableDebug() { 137 | DEBUG = true; 138 | } 139 | 140 | /** 141 | * 142 | */ 143 | public void dispose(){ 144 | // Anything in here will be called automatically when 145 | // the parent sketch shuts down. For instance, this might 146 | // shut down a thread used by this library. 147 | try { 148 | System.out.println("Closing websockets..."); 149 | server.stop(); 150 | System.out.println("...websockets closed"); 151 | } catch (Exception e) { 152 | e.printStackTrace(); 153 | } 154 | } 155 | } 156 | -------------------------------------------------------------------------------- /src/websockets/WebsocketServerController.java: -------------------------------------------------------------------------------- 1 | package websockets; 2 | 3 | import java.lang.reflect.Method; 4 | import java.math.BigInteger; 5 | import java.security.SecureRandom; 6 | import java.util.HashMap; 7 | import java.nio.ByteBuffer; 8 | import java.io.IOException; 9 | import java.util.Map; 10 | 11 | /** 12 | * 13 | * @author Lasse Steenbock Vestergaard 14 | * @author Abe Pazos (changes) 15 | * 16 | * Intermediate class responsible for keeping track of client connections, 17 | * and propagate method calls between the websocket events and the Processing sketch 18 | * 19 | */ 20 | public class WebsocketServerController { 21 | 22 | private final Map memberUIDs = 23 | new HashMap<>(); 24 | private final Map memberSockets = 25 | new HashMap<>(); 26 | 27 | private final Object listenerObject; 28 | private Method eventListener = null; 29 | private Method eventBinaryListener = null; 30 | 31 | private static SecureRandom random = new SecureRandom(); 32 | 33 | /** 34 | * 35 | * Initiates the communication management between websocket events and 36 | * the Processing sketch 37 | * 38 | * @param listenerObject The Processing sketch's PApplet object 39 | */ 40 | public WebsocketServerController(Object listenerObject) { 41 | this.listenerObject = listenerObject; 42 | 43 | try { 44 | eventListener = listenerObject.getClass().getMethod( 45 | "webSocketServerEvent", String.class); 46 | } catch (NoSuchMethodException e) { 47 | // ok to ignore 48 | } 49 | 50 | try { 51 | eventBinaryListener = listenerObject.getClass().getMethod( 52 | "webSocketServerEvent", byte[].class, int.class, int.class); 53 | } catch (NoSuchMethodException e) { 54 | // ok to ignore 55 | } 56 | } 57 | 58 | /** 59 | * 60 | * Add new client to the list of all active clients 61 | * 62 | * @param socket The specific connection between client and server 63 | */ 64 | public void join(WebsocketServerEvents socket) { 65 | String IP = getIP(socket); 66 | String UID = getUID(); 67 | 68 | memberUIDs.put(socket, UID); 69 | memberSockets.put(UID, socket); 70 | 71 | try { 72 | Method m = listenerObject.getClass().getMethod( 73 | "webSocketConnectEvent", String.class, String.class); 74 | m.invoke(listenerObject, UID, IP); 75 | } catch (NoSuchMethodException e) { 76 | // ok to ignore 77 | } catch (Exception e) { 78 | e.printStackTrace(); 79 | } 80 | } 81 | 82 | /** 83 | * 84 | * Removes client to the list of all active clients 85 | * 86 | * @param socket The specific connection between client and server 87 | */ 88 | public void remove(WebsocketServerEvents socket) { 89 | String IP = getIP(socket); 90 | String UID = memberUIDs.get(socket); 91 | 92 | memberUIDs.remove(socket); 93 | memberSockets.remove(UID); 94 | 95 | try { 96 | Method m = listenerObject.getClass().getMethod( 97 | "webSocketDisconnectEvent", String.class, String.class); 98 | m.invoke(listenerObject, UID, IP); 99 | } catch (NoSuchMethodException e) { 100 | // ok to ignore 101 | } catch (Exception e) { 102 | e.printStackTrace(); 103 | } 104 | 105 | } 106 | 107 | /** 108 | * 109 | * Writes a message to all active clients 110 | * 111 | * @param message String to send to all clients 112 | */ 113 | public void writeAllMembers(String message) { 114 | for (WebsocketServerEvents member : memberUIDs.keySet()) { 115 | member.session.getRemote().sendStringByFuture(message); 116 | } 117 | } 118 | 119 | /** 120 | * 121 | * Writes a message to all active clients 122 | * 123 | * @param data byte[] to send to all clients 124 | */ 125 | public void writeAllMembers(byte[] data) { 126 | for (WebsocketServerEvents member : memberUIDs.keySet()) { 127 | try { 128 | ByteBuffer buf = ByteBuffer.wrap(data); 129 | member.session.getRemote().sendBytes(buf); 130 | } catch (IOException e) { 131 | e.printStackTrace(); 132 | } 133 | } 134 | } 135 | 136 | /** 137 | * 138 | * Send message to one member 139 | * 140 | * @param message String to send to client 141 | * @param uid id of the specific client 142 | */ 143 | public void writeSpecificMember(String message, String uid) { 144 | WebsocketServerEvents member = memberSockets.get(uid); 145 | member.session.getRemote().sendStringByFuture(message); 146 | } 147 | 148 | /** 149 | * 150 | * Send message to one member 151 | * 152 | * @param data String to send to client 153 | * @param uid id of the specific client 154 | */ 155 | public void writeSpecificMember(byte[] data, String uid) { 156 | WebsocketServerEvents member = memberSockets.get(uid); 157 | try { 158 | ByteBuffer buf = ByteBuffer.wrap(data); 159 | member.session.getRemote().sendBytes(buf); 160 | } catch (IOException e) { 161 | e.printStackTrace(); 162 | } 163 | } 164 | 165 | /** 166 | * 167 | * Sends incoming message directly to the Processing sketch's websocket event function 168 | * 169 | * @param message The message that has been received 170 | */ 171 | public void sendToOnMessageListener(String message){ 172 | if (eventListener != null) { 173 | try { 174 | eventListener.invoke(listenerObject, message); 175 | } catch (Exception e) { 176 | System.err.println("Disabling webSocketEvent()"); 177 | e.printStackTrace(); 178 | eventListener = null; 179 | } 180 | } 181 | } 182 | 183 | public void sendToOnBinaryListener(byte[] buf, int offset, int length){ 184 | if (eventBinaryListener != null) { 185 | try { 186 | eventBinaryListener 187 | .invoke(listenerObject, buf, offset, length); 188 | } catch (Exception e) { 189 | System.err.println("Disabling webSocketEvent()"); 190 | e.printStackTrace(); 191 | eventBinaryListener = null; 192 | } 193 | } 194 | } 195 | 196 | /** 197 | * Generate 198 | * @return 199 | */ 200 | private static String getUID() { 201 | return new BigInteger(130, random).toString(24); 202 | } 203 | 204 | private static String getIP(WebsocketServerEvents socket) { 205 | return socket.session.getRemoteAddress().getAddress().toString(); 206 | } 207 | } 208 | -------------------------------------------------------------------------------- /src/websockets/WebsocketServerCreator.java: -------------------------------------------------------------------------------- 1 | package websockets; 2 | 3 | import org.eclipse.jetty.websocket.servlet.ServletUpgradeRequest; 4 | import org.eclipse.jetty.websocket.servlet.ServletUpgradeResponse; 5 | import org.eclipse.jetty.websocket.servlet.WebSocketCreator; 6 | 7 | /** 8 | * 9 | * @author Lasse Steenbock Vestergaard 10 | * 11 | * Class specific to the underlying websocket implementation (Jetty) 12 | * 13 | */ 14 | public class WebsocketServerCreator implements WebSocketCreator{ 15 | private WebsocketServerController ctrl; 16 | 17 | public WebsocketServerCreator(WebsocketServerController ctrl){ 18 | this.ctrl = ctrl; 19 | } 20 | 21 | public Object createWebSocket(ServletUpgradeRequest request, ServletUpgradeResponse response){ 22 | return new WebsocketServerEvents(ctrl); 23 | } 24 | } -------------------------------------------------------------------------------- /src/websockets/WebsocketServerEvents.java: -------------------------------------------------------------------------------- 1 | package websockets; 2 | 3 | import org.eclipse.jetty.websocket.api.Session; 4 | import org.eclipse.jetty.websocket.api.annotations.OnWebSocketClose; 5 | import org.eclipse.jetty.websocket.api.annotations.OnWebSocketConnect; 6 | import org.eclipse.jetty.websocket.api.annotations.OnWebSocketError; 7 | import org.eclipse.jetty.websocket.api.annotations.OnWebSocketMessage; 8 | import org.eclipse.jetty.websocket.api.annotations.WebSocket; 9 | import java.nio.ByteBuffer; 10 | 11 | /** 12 | * 13 | * @author Lasse Steenbock Vestergaard 14 | * @author Abe Pazos (changes) 15 | * 16 | * This class is responsible for handling all events 17 | * relating to the websocket server 18 | * 19 | */ 20 | @WebSocket 21 | public class WebsocketServerEvents { 22 | 23 | public Session session; 24 | public WebsocketServerController ctrl; 25 | 26 | public WebsocketServerEvents(WebsocketServerController ctrl) { 27 | this.ctrl = ctrl; 28 | } 29 | 30 | /** 31 | * 32 | * Handles new client connections, and adding the client to a list of clients, so that we can send messages to it later 33 | * 34 | * @param session The connection session between the server and a specific client (not all clients!) 35 | * 36 | */ 37 | @OnWebSocketConnect 38 | public void handleConnect(Session session) { 39 | this.session = session; 40 | ctrl.join(this); 41 | } 42 | 43 | /** 44 | * 45 | * Handles closing down a specific client connection, and removes the client from the list of clients 46 | * 47 | * @param statusCode Reason code for closing the connection 48 | * @param reason Description of close down reason 49 | */ 50 | @OnWebSocketClose 51 | public void handleClose(int statusCode, String reason) { 52 | ctrl.remove(this); 53 | } 54 | 55 | /** 56 | * 57 | * Handles incoming messages, and passes them on to the Processing sketch's websocket event method 58 | * 59 | * @param message The incoming message 60 | */ 61 | @OnWebSocketMessage 62 | public void handleMessage(String message) { 63 | ctrl.sendToOnMessageListener(message); 64 | } 65 | 66 | @OnWebSocketMessage 67 | public void handleBinary(byte[] buf, int offset, int length) { 68 | ctrl.sendToOnBinaryListener(buf, offset, length); 69 | } 70 | 71 | /** 72 | * 73 | * Handling connection errors and writes the to the console 74 | * 75 | * @param error The error that occurred 76 | */ 77 | @OnWebSocketError 78 | public void handleError(Throwable error) { 79 | error.printStackTrace(); 80 | } 81 | } -------------------------------------------------------------------------------- /webSockets.zip: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alexandrainst/processing_websockets/ceec7cf5cd3e07b8a3fb5552f291e363ae10e27c/webSockets.zip --------------------------------------------------------------------------------