-
Notifications
You must be signed in to change notification settings - Fork 33
Add web socket interception example #194
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 5 commits
4254ce1
e0af385
18dad41
1526252
0e33977
121ff4f
4285da6
6bdd47b
3773e56
4ab5168
ca9b4fd
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,109 @@ | ||
| /* | ||
| * Copyright 2025, TeamDev. All rights reserved. | ||
| * | ||
| * Redistribution and use in source and/or binary forms, with or without | ||
| * modification, must retain the above copyright notice and the following | ||
| * disclaimer. | ||
| * | ||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
| * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
| * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
| * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
| * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
| * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
| * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| */ | ||
|
|
||
| package com.teamdev.jxbrowser.examples; | ||
|
|
||
| import static com.teamdev.jxbrowser.engine.RenderingMode.OFF_SCREEN; | ||
|
|
||
| import com.teamdev.jxbrowser.browser.callback.InjectJsCallback; | ||
| import com.teamdev.jxbrowser.engine.Engine; | ||
| import com.teamdev.jxbrowser.js.JsAccessible; | ||
| import com.teamdev.jxbrowser.js.JsObject; | ||
|
|
||
| /** | ||
| * This example demonstrates how to intercept web socket data by using JS-Java | ||
| * bridget capabilities. | ||
| */ | ||
| public class WebSocketDataInterceptor { | ||
kyrylo-pshenychnyi marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| private static final String JAVA_SCRIPT = """ | ||
| var oldSocket = window.WebSocket; | ||
| window.WebSocket = function (url){ | ||
kyrylo-pshenychnyi marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| var socket = new oldSocket(url); | ||
| socket.onopen = () => { | ||
| window.websocketCallback.socketOpened(socket); | ||
| this.onopen(); | ||
| }; | ||
| socket.onmessage = (message) => { | ||
| window.websocketCallback.messageReceived(socket,message.data); | ||
| this.onmessage(message); | ||
| }; | ||
| var onclose = socket.onclose; | ||
| socket.onclose = (closeEvent) => { | ||
| this.onclose(); | ||
| window.websocketCallback.socketClosed(closeEvent); | ||
| this.close(closeEvent); | ||
| }; | ||
| this.close = (event)=> {socket.close();}; | ||
| this.send = (data) => { | ||
| window.websocketCallback.beforeSendData(socket,data); | ||
| socket.send(data); | ||
| }; | ||
| };"""; | ||
|
|
||
| public static void main(String[] args) { | ||
| try (var engine = Engine.newInstance(OFF_SCREEN)) { | ||
| var browser = engine.newBrowser(); | ||
| browser.set(InjectJsCallback.class, params -> { | ||
| var frame = params.frame(); | ||
| JsObject jsObject = frame.executeJavaScript("window"); | ||
| if (jsObject != null) { | ||
| jsObject.putProperty("websocketCallback", new WebSocketCallback()); | ||
kyrylo-pshenychnyi marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| } | ||
| frame.executeJavaScript(JAVA_SCRIPT); | ||
| return InjectJsCallback.Response.proceed(); | ||
| }); | ||
|
|
||
| browser.navigation().loadUrlAndWait("https://www.teamdev.com/jxbrowser#features"); | ||
|
||
| } | ||
| } | ||
|
|
||
| /** | ||
| * A JS-accessible class used as web socket events listener in JS. | ||
kyrylo-pshenychnyi marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| * | ||
| * <p>The class is marked with [JsAccessible] annotation to tell JavaScript | ||
kyrylo-pshenychnyi marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| * that all public methods of the injected object can be invoked from | ||
| * the JavaScript side. | ||
| * | ||
| * <p>Please note, only public classes and static nested classes can be injected | ||
| * into JavaScript. | ||
| */ | ||
| @JsAccessible | ||
| private static class WebSocketCallback { | ||
| @SuppressWarnings("unused") // To be called from JavaScript. | ||
| public void socketClosed(JsObject closeEvent) { | ||
| System.out.println("WebSocketCallback.socketClosed"); | ||
| } | ||
|
|
||
| @SuppressWarnings("unused") // To be called from JavaScript. | ||
| public void messageReceived(JsObject socket, Object data) { | ||
| System.out.println("WebSocketCallback.messageReceived: " + data); | ||
| } | ||
|
|
||
| @SuppressWarnings("unused") // To be called from JavaScript. | ||
| public void socketOpened(JsObject socket) { | ||
| System.out.println("WebSocketCallback.socketOpened"); | ||
| } | ||
|
|
||
| @SuppressWarnings("unused") // To be called from JavaScript. | ||
| public void beforeSendData(JsObject socket, Object data) { | ||
| System.out.println("WebSocketCallback.beforeSendData: " + data); | ||
| } | ||
| } | ||
| } | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,104 @@ | ||
| /* | ||
| * Copyright 2025, TeamDev. All rights reserved. | ||
kyrylo-pshenychnyi marked this conversation as resolved.
Outdated
Show resolved
Hide resolved
|
||
| * | ||
| * Redistribution and use in source and/or binary forms, with or without | ||
| * modification, must retain the above copyright notice and the following | ||
| * disclaimer. | ||
| * | ||
| * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | ||
| * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | ||
| * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | ||
| * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT | ||
| * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, | ||
| * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT | ||
| * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, | ||
| * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY | ||
| * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT | ||
| * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE | ||
| * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | ||
| */ | ||
| package com.teamdev.jxbrowser.examples | ||
|
|
||
| import com.teamdev.jxbrowser.browser.callback.InjectJsCallback | ||
| import com.teamdev.jxbrowser.dsl.Engine | ||
| import com.teamdev.jxbrowser.dsl.register | ||
| import com.teamdev.jxbrowser.engine.RenderingMode | ||
| import com.teamdev.jxbrowser.js.JsAccessible | ||
| import com.teamdev.jxbrowser.js.JsObject | ||
|
|
||
| /** | ||
| * This example demonstrates how to intercept web socket data by using JS-Kotlin | ||
| * bridget capabilities. | ||
| */ | ||
| fun main() { | ||
| val engine = Engine(RenderingMode.OFF_SCREEN) | ||
| val browser = engine.newBrowser() | ||
| browser.register(InjectJsCallback { params -> | ||
| val frame = params.frame() | ||
| val jsWindow = frame.executeJavaScript<JsObject>("window")!! | ||
| jsWindow.putProperty("websocketCallback", WebSocketCallback()) | ||
| frame.executeJavaScript<Any>(JAVA_SCRIPT) | ||
| InjectJsCallback.Response.proceed() | ||
| }) | ||
| browser.navigation() | ||
| .loadUrlAndWait("https://www.teamdev.com/jxbrowser#features") | ||
| engine.close() | ||
| } | ||
|
|
||
| /** | ||
| * A JS-accessible class used as web socket events listener in JS. | ||
| * | ||
| * The class is marked with [JsAccessible] annotation to tell JavaScript | ||
| * that all public methods of the injected object can be invoked from | ||
| * the JavaScript side. | ||
| * | ||
| * Please note, only public classes and static nested classes can be injected | ||
| * into JavaScript. | ||
| */ | ||
| @JsAccessible | ||
| class WebSocketCallback { | ||
|
|
||
| @Suppress("unused") // To be called from JavaScript. | ||
| fun socketClosed(closeEvent: JsObject?) { | ||
| println("WebSocketCallback.socketClosed: $closeEvent") | ||
| } | ||
|
|
||
| @Suppress("unused") // To be called from JavaScript. | ||
| fun messageReceived(socket: JsObject?, data: Any) { | ||
| println("WebSocketCallback.messageReceived: $socket $data") | ||
| } | ||
|
|
||
| @Suppress("unused") // To be called from JavaScript. | ||
| fun socketOpened(socket: JsObject?) { | ||
| println("WebSocketCallback.socketOpened : $socket") | ||
| } | ||
|
|
||
| @Suppress("unused") // To be called from JavaScript. | ||
| fun beforeSendData(socket: JsObject?, data: Any) { | ||
| println("WebSocketCallback.beforeSendData: $socket $data") | ||
| } | ||
| } | ||
|
|
||
| private const val JAVA_SCRIPT = ("var oldSocket = window.WebSocket;\n" | ||
| + " window.WebSocket = function (url){\n" | ||
| + " var socket = new oldSocket(url);\n" | ||
| + " socket.onopen = () => {\n" | ||
| + " window.websocketCallback.socketOpened(socket);\n" | ||
| + " this.onopen();\n" | ||
| + " };\n" | ||
| + " socket.onmessage = (message) => {\n" | ||
| + " window.websocketCallback.messageReceived(socket,message.data);\n" | ||
| + " this.onmessage(message);\n" | ||
| + " };\n" | ||
| + " var onclose = socket.onclose;\n" | ||
| + " socket.onclose = (closeEvent) => {\n" | ||
| + " this.onclose();\n" | ||
| + " window.websocketCallback.socketClosed(closeEvent);\n" | ||
| + " this.close(closeEvent);\n" | ||
| + " };\n" | ||
| + " this.close = (event)=> {socket.close();};\n" | ||
| + " this.send = (data) => {\n" | ||
| + " window.websocketCallback.beforeSendData(socket,data);\n" | ||
| + " socket.send(data);\n" | ||
| + " };\n" | ||
| + " };") | ||
Uh oh!
There was an error while loading. Please reload this page.