Skip to content

Commit

Permalink
Add ability to customize ping messages with custom data, see iss… (#944)
Browse files Browse the repository at this point in the history
Add ability to customize ping messages with custom data, see issue#941
  • Loading branch information
marci4 committed Nov 21, 2019
2 parents 6230be5 + d64295e commit 89df856
Show file tree
Hide file tree
Showing 4 changed files with 135 additions and 10 deletions.
16 changes: 16 additions & 0 deletions src/main/java/org/java_websocket/WebSocketAdapter.java
Expand Up @@ -40,6 +40,8 @@
**/
public abstract class WebSocketAdapter implements WebSocketListener {

private PingFrame pingFrame;

/**
* This default implementation does not do anything. Go ahead and overwrite it.
*
Expand Down Expand Up @@ -85,4 +87,18 @@ public void onWebsocketPing( WebSocket conn, Framedata f ) {
public void onWebsocketPong( WebSocket conn, Framedata f ) {
//To overwrite
}

/**
* Default implementation for onPreparePing, returns a (cached) PingFrame that has no application data.
* @see org.java_websocket.WebSocketListener#onPreparePing(WebSocket)
*
* @param conn The <tt>WebSocket</tt> connection from which the ping frame will be sent.
* @return PingFrame to be sent.
*/
@Override
public PingFrame onPreparePing(WebSocket conn) {
if(pingFrame == null)
pingFrame = new PingFrame();
return pingFrame;
}
}
16 changes: 6 additions & 10 deletions src/main/java/org/java_websocket/WebSocketImpl.java
Expand Up @@ -161,11 +161,6 @@ public class WebSocketImpl implements WebSocket {
*/
private final Object synchronizeWriteObject = new Object();

/**
* Attribute to cache a ping frame
*/
private PingFrame pingFrame;

/**
* Attribute to store connection attachment
* @since 1.3.7
Expand Down Expand Up @@ -658,11 +653,12 @@ public void sendFrame( Framedata framedata ) {
send( Collections.singletonList( framedata ) );
}

public void sendPing() {
if( pingFrame == null ) {
pingFrame = new PingFrame();
}
sendFrame( pingFrame );
public void sendPing() throws NullPointerException {
// Gets a PingFrame from WebSocketListener(wsl) and sends it.
PingFrame pingFrame = wsl.onPreparePing(this);
if(pingFrame == null)
throw new NullPointerException("onPreparePing(WebSocket) returned null. PingFrame to sent can't be null.");
sendFrame(pingFrame);
}

@Override
Expand Down
9 changes: 9 additions & 0 deletions src/main/java/org/java_websocket/WebSocketListener.java
Expand Up @@ -32,6 +32,7 @@
import org.java_websocket.exceptions.InvalidDataException;
import org.java_websocket.framing.CloseFrame;
import org.java_websocket.framing.Framedata;
import org.java_websocket.framing.PingFrame;
import org.java_websocket.handshake.ClientHandshake;
import org.java_websocket.handshake.Handshakedata;
import org.java_websocket.handshake.ServerHandshake;
Expand Down Expand Up @@ -169,6 +170,14 @@ public interface WebSocketListener {
*/
void onWebsocketPing( WebSocket conn, Framedata f );

/**
* Called just before a ping frame is sent, in order to allow users to customize their ping frame data.
*
* @param conn The <tt>WebSocket</tt> connection from which the ping frame will be sent.
* @return PingFrame to be sent.
*/
PingFrame onPreparePing(WebSocket conn );

/**
* Called when a pong frame is received.
*
Expand Down
104 changes: 104 additions & 0 deletions src/test/java/org/java_websocket/issues/Issue941Test.java
@@ -0,0 +1,104 @@
/*
* Copyright (c) 2010-2019 Nathan Rajlich
*
* Permission is hereby granted, free of charge, to any person
* obtaining a copy of this software and associated documentation
* files (the "Software"), to deal in the Software without
* restriction, including without limitation the rights to use,
* copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following
* conditions:
*
* The above copyright notice and this permission notice shall be
* included in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
* OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
* NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
* HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
* WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/

package org.java_websocket.issues;

import org.java_websocket.WebSocket;
import org.java_websocket.client.WebSocketClient;
import org.java_websocket.framing.Framedata;
import org.java_websocket.framing.PingFrame;
import org.java_websocket.handshake.ClientHandshake;
import org.java_websocket.handshake.ServerHandshake;
import org.java_websocket.server.WebSocketServer;
import org.java_websocket.util.SocketUtil;
import org.junit.Test;

import java.net.InetSocketAddress;
import java.net.URI;
import java.nio.ByteBuffer;
import java.util.concurrent.CountDownLatch;

import static org.junit.Assert.assertArrayEquals;

public class Issue941Test {

private CountDownLatch pingLatch = new CountDownLatch(1);
private CountDownLatch pongLatch = new CountDownLatch(1);
private byte[] pingBuffer, receivedPingBuffer, pongBuffer;

@Test
public void testIssue() throws Exception {
int port = SocketUtil.getAvailablePort();
WebSocketClient client = new WebSocketClient(new URI( "ws://localhost:" + port)) {
@Override
public void onOpen(ServerHandshake handshakedata) { }
@Override
public void onMessage(String message) { }
@Override
public void onClose(int code, String reason, boolean remote) { }
@Override
public void onError(Exception ex) { }
@Override
public PingFrame onPreparePing(WebSocket conn) {
PingFrame frame = new PingFrame();
pingBuffer = new byte[]{1,2,3,4,5,6,7,8,9,10};
frame.setPayload(ByteBuffer.wrap(pingBuffer));
return frame;
}
@Override
public void onWebsocketPong(WebSocket conn, Framedata f) {
pongBuffer = f.getPayloadData().array();
pongLatch.countDown();
}
};

WebSocketServer server = new WebSocketServer(new InetSocketAddress(port)) {
@Override
public void onOpen(WebSocket conn, ClientHandshake handshake) { }
@Override
public void onClose(WebSocket conn, int code, String reason, boolean remote) { }
@Override
public void onMessage(WebSocket conn, String message) { }
@Override
public void onError(WebSocket conn, Exception ex) { }
@Override
public void onStart() { }
@Override
public void onWebsocketPing(WebSocket conn, Framedata f) {
receivedPingBuffer = f.getPayloadData().array();
super.onWebsocketPing(conn, f);
pingLatch.countDown();
}
};

server.start();
client.connectBlocking();
client.setConnectionLostTimeout(1);
pingLatch.await();
assertArrayEquals(pingBuffer, receivedPingBuffer);
pongLatch.await();
assertArrayEquals(pingBuffer, pongBuffer);
}
}

0 comments on commit 89df856

Please sign in to comment.