Add support for sending binary data in websockets
Summary:This is a reprise of #6327, but with iOS 7.0 compatibility and less `package.json` changes. **Test Plan:** Load WebSocketExample in UIExplorer app and start websocket test server script (both provided in #6889) and test sending binary data on both iOS and Android Closes https://github.com/facebook/react-native/pull/6961 Differential Revision: D3202022 Pulled By: mkonicek fb-gh-sync-id: 38843d0a9c0172971c5c70a5139ded04042b280a fbshipit-source-id: 38843d0a9c0172971c5c70a5139ded04042b280a
This commit is contained in:
parent
ad15b74aae
commit
ed930b4710
|
@ -31,7 +31,7 @@ const respondWithBinary = process.argv.indexOf('--binary') !== -1;
|
|||
const server = new WebSocket.Server({port: 5555});
|
||||
server.on('connection', (ws) => {
|
||||
ws.on('message', (message) => {
|
||||
console.log('Received message: %s', message);
|
||||
console.log('Received message:', message);
|
||||
if (respondWithBinary) {
|
||||
message = new Buffer(message);
|
||||
}
|
||||
|
|
|
@ -67,6 +67,12 @@ RCT_EXPORT_METHOD(send:(NSString *)message socketID:(nonnull NSNumber *)socketID
|
|||
[_sockets[socketID] send:message];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(sendBinary:(NSString *)base64String socketID:(nonnull NSNumber *)socketID)
|
||||
{
|
||||
NSData *message = [[NSData alloc] initWithBase64EncodedString:base64String options:0];
|
||||
[_sockets[socketID] send:message];
|
||||
}
|
||||
|
||||
RCT_EXPORT_METHOD(close:(nonnull NSNumber *)socketID)
|
||||
{
|
||||
[_sockets[socketID] close];
|
||||
|
|
|
@ -21,6 +21,18 @@ const base64 = require('base64-js');
|
|||
|
||||
import type EventSubscription from 'EventSubscription';
|
||||
|
||||
type ArrayBufferView =
|
||||
Int8Array |
|
||||
Uint8Array |
|
||||
Uint8ClampedArray |
|
||||
Int16Array |
|
||||
Uint16Array |
|
||||
Int32Array |
|
||||
Uint32Array |
|
||||
Float32Array |
|
||||
Float64Array |
|
||||
DataView;
|
||||
|
||||
const CONNECTING = 0;
|
||||
const OPEN = 1;
|
||||
const CLOSING = 2;
|
||||
|
@ -94,18 +106,31 @@ class WebSocket extends EventTarget(WEBSOCKET_EVENTS) {
|
|||
this._close(code, reason);
|
||||
}
|
||||
|
||||
send(data: any): void {
|
||||
send(data: string | ArrayBuffer | ArrayBufferView): void {
|
||||
if (this.readyState === this.CONNECTING) {
|
||||
throw new Error('INVALID_STATE_ERR');
|
||||
}
|
||||
|
||||
if (typeof data === 'string') {
|
||||
RCTWebSocketModule.send(data, this._socketId);
|
||||
} else if (data instanceof ArrayBuffer) {
|
||||
console.warn('Sending ArrayBuffers is not yet supported');
|
||||
} else {
|
||||
throw new Error('Not supported data type');
|
||||
return;
|
||||
}
|
||||
|
||||
// Maintain iOS 7 compatibility which doesn't have JS typed arrays.
|
||||
if (typeof ArrayBuffer !== 'undefined' &&
|
||||
typeof Uint8Array !== 'undefined') {
|
||||
if (ArrayBuffer.isView(data)) {
|
||||
// $FlowFixMe: no way to assert that 'data' is indeed an ArrayBufferView now
|
||||
data = data.buffer;
|
||||
}
|
||||
if (data instanceof ArrayBuffer) {
|
||||
data = base64.fromByteArray(new Uint8Array(data));
|
||||
RCTWebSocketModule.sendBinary(data, this._socketId);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
throw new Error('Unsupported data type');
|
||||
}
|
||||
|
||||
_close(code?: number, reason?: string): void {
|
||||
|
|
|
@ -44,6 +44,7 @@ import java.util.concurrent.TimeUnit;
|
|||
|
||||
import okio.Buffer;
|
||||
import okio.BufferedSource;
|
||||
import okio.ByteString;
|
||||
|
||||
public class WebSocketModule extends ReactContextBaseJavaModule {
|
||||
|
||||
|
@ -216,6 +217,22 @@ public class WebSocketModule extends ReactContextBaseJavaModule {
|
|||
}
|
||||
}
|
||||
|
||||
@ReactMethod
|
||||
public void sendBinary(String base64String, int id) {
|
||||
WebSocket client = mWebSocketConnections.get(id);
|
||||
if (client == null) {
|
||||
// This is a programmer error
|
||||
throw new RuntimeException("Cannot send a message. Unknown WebSocket id " + id);
|
||||
}
|
||||
try {
|
||||
client.sendMessage(
|
||||
WebSocket.PayloadType.BINARY,
|
||||
new Buffer().write(ByteString.decodeBase64(base64String)));
|
||||
} catch (IOException | IllegalStateException e) {
|
||||
notifyWebSocketFailed(id, e.getMessage());
|
||||
}
|
||||
}
|
||||
|
||||
private void notifyWebSocketFailed(int id, String message) {
|
||||
WritableMap params = Arguments.createMap();
|
||||
params.putInt("id", id);
|
||||
|
|
Loading…
Reference in New Issue