Android Pusher not connecting to Private Channels - android

I am trying to implement pusher chat in my Android Application, i am able to connect with pusher, got the response as CONNECTED. But not able to connect to Private channels(Local server). Can anyone help on this.
adding the code below.
Thanks in advance
final HttpAuthorizer authorizer = new HttpAuthorizer(myurl);
authorizer.setHeaders(getMapAuthorizationHeaders());
PusherOptions options = new PusherOptions().setAuthorizer(authorizer);
final Pusher pusher = new Pusher("pusher_key", options);
pusher.connect(new com.pusher.client.connection.ConnectionEventListener() {
#Override
public void onConnectionStateChange(ConnectionStateChange connectionStateChange) {
Log.e("connectionStateChange" , connectionStateChange.getCurrentState().toString());
if (connectionStateChange.getCurrentState() == ConnectionState.CONNECTED) {
SOCKET_ID = pusher.getConnection().getSocketId();
Log.e("SOCKET_ID" , ""+SOCKET_ID);
Channel channel = pusher.subscribePrivate(PUSH_CHANNEL, new PrivateChannelEventListener() {
#Override
public void onAuthenticationFailure(String s, Exception e) {
Log.e("PUSHER", "Channel subscription authorization failed");
}
#Override
public void onSubscriptionSucceeded(String s) {
Log.e("PUSHER", "Channel subscription authorization succeeded");
}
#Override
public void onEvent(String s, String s2, String s3) {
Log.e("PUSHER", "An event with name " + s2 + " was delivered!!");
}
}, "my-event");
}
}
#Override
public void onError(String s, String s1, Exception e) {
}
});
public static HashMap<String, String> getMapAuthorizationHeaders() {
try {
HashMap<String, String> authHeader = new HashMap<>();
authHeader.put("HeaderKey1", "HeaderValue1");
authHeader.put("HeaderKey2", "HeaderValue2");
return authHeader;
} catch (Exception e) {
return null;
}
}

Can I assume that where you've put "pusher_key", you've just added this for security purposes on here, and in your application you're actually using your key?
Other than that, where are you defining PUSH_CHANNEL for: pusher.subscribePrivate(PUSH_CHANNEL,

Related

samsung device not connect to other device using web socket

Now i'm try to connect with other device using samsung S6 Lite. Here i have a problem while connecting to the other device it's trying to connect and after few second it's OnClose method will call in my web socket listener.
I have tried on same thing in Samsung S7, Samsung S5 and emulator it's working fine. Only i got the connection issue in Samsung S6(OS: Android 11).
Node.js
const http = require('http');
const WebSocketServer = require('websocket').server;
const server = http.createServer();
server.listen(8080);
const wsServer = new WebSocketServer({
httpServer: server
});
wsServer.on('request', function(request) {
const connection = request.accept(null, request.origin);
console.log('Server Connected')
connection.on('message', function(message) {
console.log('Received Message:', message.utf8Data);
//connection.sendUTF('Hi this is WebSocket server!');
connection.sendUTF('Socket server conne');
});
connection.on('close', function(reasonCode, description) {
console.log('Client has disconnected.',description.utf8Data);
});
connection.on('error', function(error){
console.log('Client has error',error.utf8Data);
});
connection.on('frame', function(frame){
console.log('Client has frame');
});
});
wsServer.on('connect',function(connection){
console.log('Server connection status: ');
connection.on('message', function(message){
console.log('Server Received Message:', message.utf8Data);
});
});
Android Connection Code:
public void test() {
try {
URI uri;
try {
uri = new URI("ws://localhost:8080/test");
} catch (URISyntaxException e) {
e.printStackTrace();
return;
}
String myAndroidDeviceId = Settings.Secure.getString(getApplicationContext().getContentResolver(), ANDROID_ID);
Map<String, String> stringStringMap = new HashMap<>();
stringStringMap.put("device", "device," + myAndroidDeviceId);
String temp[] = {"device:device"};
cc = new WebSocketClient(uri) {
#Override
public void onOpen(ServerHandshake serverHandshake) {
String str = android.os.Build.MODEL;
String record = "Device Name : " + str;
// cc.send(String.valueOf(record));
cc.send(record);
System.out.println("Address" + cc.getRemoteSocketAddress());
Log.i("Websocket", "Opened");
System.out.println("SocketIPAddress--->Opened--->");
}
#Override
public void onMessage(String s) {
final String message = s;
System.out.println(message);
System.out.println("SocketIPAddress--->onMessage--->" + s);
updateUI(message);
}
#Override
public void onClose(int i, String s, boolean b) {
// Log.i("Websocket", "Closed " + s);
System.out.println("SocketIPAddress--->onClose--->" + s);
//updateUI("Disconnected");
}
#Override
public void onError(final Exception e) {
System.out.println("SocketIPAddress--->onError--->" + e.getMessage());
}
};
cc.connect();
} catch (Exception ex) {
Log.i("ErrorMsg", ex.getMessage());
}
}
Any one please help to fix this issue. Thanks

Android WebRTC remote stream not displaying on SurfaceView, getting 0 frames

I'm attempting to stream my webcam locally from a webpage on my computer to an Android app (native WebRTC). I'm using WebRTC for the peer connection and NodeJS with Socket.io for signaling. When I initiate the video stream all sdp appears to be set correctly, but no track plays on my Andorid surface view. All I get is a black screen and this console output:
2020-08-19 13:23:19.667 30492-31575/com.example.demowebrtcclient I/org.webrtc.Logging: EglRenderer: video_viewDuration: 4050 ms. Frames received: 0. Dropped: 0. Rendered: 0. Render fps: .0. Average render time: NA. Average swapBuffer time: NA.
Here's my code, sorry there's so much I just don't know where the root of the problem is.
Peer 1 (Webpage, JS)
navigator.mediaDevices.getUserMedia({audio: true, video: true})
.then(function(s) {
stream = s;
video.srcObject = stream;
video.play();
});
function startStream() {
socket.emit('broadcaster');
}
socket.on('answer', function(id, description) {
let RTCDescription = description;
if (isAndroid) {
RTCDescription = new RTCSessionDescription();
RTCDescription.sdp = description;
RTCDescription.type = "answer";
console.log("Answer received");
}
console.log(RTCDescription);
peerConnection.setRemoteDescription(RTCDescription);
});
socket.on('watcher', function(id) {
peerConnection = new RTCPeerConnection(config);
// peerConnections[id] = peerConnection;
stream.getTracks().forEach(track => peerConnection.addTrack(track, stream));
peerConnection.createOffer()
.then(function(sdp) {
peerConnection.setLocalDescription(sdp);
})
.then(function() {
socket.emit('offer', id, peerConnection.localDescription);
})
peerConnection.onicecandidate = function(event) {
if (event.candidate) {
socket.emit('candidate', id, event.candidate);
}
};
});
socket.on('candidate', function(id, candidate) {
console.log("Candidate recieved");
peerConnection.addIceCandidate(new RTCIceCandidate(candidate));
});
socket.on('close', function(id) {
peerConnection.close();
delete peerConnection;
});
Peer 2 (Android, Java)
private void initializePeerConnectionFactory() {
PeerConnectionFactory.InitializationOptions initOptions = PeerConnectionFactory.InitializationOptions.builder(getApplicationContext())
.setEnableInternalTracer(true)
.setFieldTrials("WebRTC-H264HighProfile/Enabled/")
.createInitializationOptions();
PeerConnectionFactory.initialize(initOptions);
VideoEncoderFactory defaultVideoEncoderFactory = new DefaultVideoEncoderFactory(rootEglBaseContext, /* enableIntelVp8Encoder */true, /* enableH264HighProfile */true);
VideoDecoderFactory defaultVideoDecoderFactory = new DefaultVideoDecoderFactory(rootEglBaseContext);
PeerConnectionFactory.Options options = new PeerConnectionFactory.Options();
options.disableEncryption = true;
options.disableNetworkMonitor = true;
factory = PeerConnectionFactory.builder()
.setVideoEncoderFactory(defaultVideoEncoderFactory)
.setVideoDecoderFactory(defaultVideoDecoderFactory)
.setOptions(options)
.createPeerConnectionFactory();
}
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
rootEglBase = EglBase.create();
rootEglBaseContext = rootEglBase.getEglBaseContext();
videoView = findViewById(R.id.video_view);
videoView.setMirror(true);
videoView.setEnableHardwareScaler(true);
videoView.init(rootEglBaseContext, null);
videoSink = new ProxyVideoSink();
iceServers = new ArrayList<>();
stunServer = (PeerConnection.IceServer.builder("stun:stun.l.google.com:19302").createIceServer());
iceServers.add(stunServer);
executor = Executors.newSingleThreadScheduledExecutor();
mediaConstraints = new MediaConstraints();
mSocket.on(Socket.EVENT_CONNECT, onConnect);
mSocket.on("offer", handleOffer);
mSocket.on("broadcaster", onBroadcast);
mSocket.on("candidate", onCandidate);
mSocket.connect();
initializePeerConnectionFactory();
}
private Emitter.Listener handleOffer = new Emitter.Listener() {
#Override
public void call(final Object... args) {
Log.d("socket", "Offer recieved");
peerConnection = factory.createPeerConnection(iceServers, observer);
String id = (String) args[0];
JSONObject data = (JSONObject) args[1];
peerConnection.setRemoteDescription(new SdpAdapter("setremote") {
#Override
public void onSetSuccess() {
peerConnection.createAnswer(new SdpAdapter("createanswer") {
#Override
public void onCreateSuccess(final SessionDescription sdp) {
super.onCreateSuccess(sdp);
Log.d("socket", "Session description " + sdp.toString() + " created");
SdpAdapter local = new SdpAdapter("setlocal") {
#Override
public void onSetSuccess() {
super.onSetSuccess();
mSocket.emit("answer" , id, peerConnection.getLocalDescription().description);
}
};
peerConnection.setLocalDescription(local, sdp);
}
}, mediaConstraints);
}
}, new SessionDescription(SessionDescription.Type.OFFER, data.optString("sdp")));
}
};
private Emitter.Listener onConnect = new Emitter.Listener() {
#Override
public void call(final Object... args) {
Log.d("socket", "Socket connected");
mSocket.emit("watcher");
}
};
private Emitter.Listener onBroadcast = new Emitter.Listener() {
#Override
public void call(final Object... args) {
Log.d("socket", "Received broadcast request");
mSocket.emit("watcher");
}
};
private Emitter.Listener onCandidate = new Emitter.Listener() {
#Override
public void call(final Object... args) {
Log.d("ice", "New ice candidate recieved");
JSONObject data = (JSONObject) args[1];
IceCandidate candidate = new IceCandidate(data.optString("sdpMid"), Integer.parseInt(data.optString("sdpMLineIndex")), data.optString("candidate"));
peerConnection.addIceCandidate(candidate);
}
};
public class SdpAdapter implements SdpObserver {
private String name;
public SdpAdapter(String name) {
this.name = name;
}
#Override
public void onCreateSuccess(SessionDescription sessionDescription) {
Log.d("socket", "SDP create success for " + name );
}
#Override
public void onSetSuccess() {
Log.d("socket", "SDP set success for " + name);
}
#Override
public void onCreateFailure(String s) {
Log.d("socket", "SDP create failure for" + s);
}
#Override
public void onSetFailure(String s) {
Log.d("socket", "SDP set failure for" + s);
}
};
public static class ProxyVideoSink implements VideoSink {
private VideoSink mTarget;
#Override
synchronized public void onFrame(VideoFrame frame) {
if (mTarget == null) {
Log.d("socket", "Dropping frame in proxy because target is null.");
return;
}
mTarget.onFrame(frame);
}
synchronized void setTarget(VideoSink target) {
this.mTarget = target;
}
}
Observer observer = new Observer() {
#Override
public void onIceCandidate(IceCandidate iceCandidate) {
Log.d("ice", iceCandidate.toString());
mSocket.emit("candidate", iceCandidate);
}
#Override
public void onAddStream(MediaStream stream) {
executor.execute(new Runnable() {
#Override
public void run() {
Log.d("socket", "Stream added");
Log.d("tracks", "Getting tracks");
VideoTrack remoteVideoTrack = (VideoTrack)stream.videoTracks.get(0);
AudioTrack remoteAudioTrack = (AudioTrack)stream.audioTracks.get(0);
Log.d("tracks", "Enabling tracks");
remoteAudioTrack.setEnabled(true);
remoteVideoTrack.setEnabled(true);
Log.d("tracks", "Adding sink");
videoSink.setTarget(videoView);
remoteVideoTrack.addSink(videoSink);
peerConnection.getStats(reports -> {
for (StatsReport report : reports) {
Log.d("Stats", "Stats: " + report.toString());
}
}, null);
}
});
}
};
}
Disabling encryption in Android will break interoperability with the browser, unless you start them in a special (insecure) mode.
options.disableEncryption = true;
A good point to get started with the Android native WebRTC API is by looking at the example App code:
https://chromium.googlesource.com/external/webrtc/+/refs/heads/master/examples/androidapp/src/org/appspot/apprtc/PeerConnectionClient.java
I'll recommend to add more logs and extend the description / question.
Recommended procedure when debugging a WebRTC issue:
Did ICE succeed? (iceConnectionState is connected) If not, look at the gathered and received candidates. Check involved firewall configurations, NAT and TURN.
Do you receive packets but no frames can be rendered? Check your codecs and encoders / decoders.

Android Pusher AuthorizationFailureException: FileNotFoundException

I've already looked over many posts in StackOverflow and their git issues. The problem with almost all of them is about header for HttpAuthorizer. But it's still not working for me. Can anyone help me to find what's wrong with my code? Thank you.
Note: I don't know if the error is on the server side, because when my team tested it with simple chat app from browser it works.
public class PusherService {
private static final String CHANNEL = "private-User." + accountId;
private static PusherService instance;
private Pusher pusher;
public static synchronized PusherService getInstance() {
if (instance == null) {
instance = new PusherService();
}
return instance;
}
private PusherService() {
pusher = initiatePusher();
}
private static Pusher initiatePusher() {
HttpAuthorizer httpAuthorizer = new HttpAuthorizer(BuildConfig.PUSHER_AUTH_URL);
Map<String, String> headers = new HashMap<>();
headers.put("Authorization", Session.getToken());
headers.put("Accept", "application/json");
headers.put("Content-Type", "application/json");
httpAuthorizer.setHeaders(headers);
PusherOptions options = new PusherOptions()
.setCluster(BuildConfig.PUSHER_CLUSTER)
.setEncrypted(true)
.setAuthorizer(httpAuthorizer);
Pusher pusher = new Pusher(BuildConfig.PUSHER_KEY, options);
pusher.connect(new ConnectionEventListener() {
#Override
public void onConnectionStateChange(ConnectionStateChange connectionStateChange) {
Log.i("Pusher", "Connection State Change: " + connectionStateChange.getCurrentState().name());
}
#Override
public void onError(String s, String s1, Exception e) {
Log.i("Pusher", String.format("Connection Error: [%s], exception: [%s]", s, e));
}
});
return pusher;
}
public PrivateChannel getChannel() {
PrivateChannel privateChannel = pusher.getPrivateChannel(CHANNEL);
if (privateChannel == null) {
privateChannel = pusher.subscribePrivate(CHANNEL, new PrivateChannelEventListener() {
#Override
public void onAuthenticationFailure(String s, Exception e) {
// Authentication failed
Log.i("Pusher", String.format("Authentication failure due to [%s], exception: [%s]", s, e));
}
#Override
public void onSubscriptionSucceeded(String s) {
Log.i("Pusher", "Private connection succeeded");
}
#Override
public void onEvent(String channel, String event, String data) {
Log.i("Pusher", data);
}
});
}
return privateChannel;
}
}
Then to test it I just called
PusherService.getInstance().getChannel();
After 2 days searching, we found the answer. I just need to remove the Content-Type header.

Android Pusher Singleton channel subscription

Hello I have implemented pusher for realtime chat and subscribing to pusher channel , but I have many activities and fragments where i want to listen to pushr events . I have added this code in every activity/fragment but the problem is that it creates multiple subscriptions for every id . I know that i have to use Singleton for this can anyone point me in the right direction to achieve this ?
Here is the code i am writing in every activity/fragment
private PusherOptions options;
private Channel channel;
private Pusher pusher;
options = new PusherOptions();
options.setCluster("ap2");
pusher = new Pusher("afbfc1f591fd7b70190f", options);
pusher.connect();
profile_id = Global.shared().preferences.getString("PROFILE_ID", " ");
channel = pusher.subscribe(profile_id);
channel.bind("message",
new SubscriptionEventListener() {
#Override
public void onEvent(String s, String s1, final String data) {
runOnUiThread(new Runnable() {
#Override
public void run() {
try {
JSONObject result = new JSONObject(data);
String message = result.getString("message");
String time = result.getString("time");
String reId = result.getString("recieverId");
new_message = message;
getConvoData(k, message);
} catch (JSONException e) {
e.printStackTrace();
}
System.out.println("DATA ====>>" + data);
}
});
}
});
okay so after trying for a while i figured it out my self i created a global class and just added pusher code to it so that it maintains just one connection for the entire lifecycle of the app
public class Global extends MultiDexApplication {
#Override
public void onCreate() {
super.onCreate();
SharedPreferences preferences = sharedInstance.getSharedPreferences(sharedInstance.getString(R.string.shared_preferences), Context.MODE_PRIVATE);
sharedInstance.preferences = preferences;
connectTopusher();
}
public void connectTopusher() {
PusherOptions options;
Channel channel;
Pusher pusher;
options = new PusherOptions();
options.setCluster("ap2");
pusher = new Pusher("afbfc1f591fd7b70190f", options);
pusher.connect();
String profile = Global.shared().preferences.getString("PROFILE_ID", "");
channel = pusher.subscribe(profile);
channel.bind("message",
new SubscriptionEventListener() {
#Override
public void onEvent(String s, String s1, final String data) {
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
try {
JSONObject result = new JSONObject(data);
String message = result.getString("message");
String time = result.getString("time");
String reId = result.getString("recieverId");
} catch (JSONException e) {
e.printStackTrace();
}
System.out.println("DATA ====>>" + data);
}
});
}
});
channel.bind("status_change", new SubscriptionEventListener() {
#Override
public void onEvent(String s, String s1, final String data) {
new Handler(Looper.getMainLooper()).post(new Runnable() {
#Override
public void run() {
try {
JSONObject result = new JSONObject(data);
} catch (JSONException e) {
e.printStackTrace();
}
System.out.println("DATA ====>>" + data);
}
});
}
});
}
You can expose channel in your Global class. That will allow you to call bind and unbind in your fragments, when they are in the foreground.
connectToPusher should just create a channel and subscribe to it.
In Global.java:
private Channel channel;
public void connectTopusher() {
PusherOptions options;
Pusher pusher;
options = new PusherOptions();
options.setCluster("ap2");
pusher = new Pusher("afbfc1f591fd7b70190f", options);
pusher.connect();
String profile = Global.shared().preferences.getString("PROFILE_ID", "");
this.channel = pusher.subscribe(profile);
}
public Channel getChannel(){
return this.channel;
}
And then in your activity/fragment you can bind/unbind your listeners to when they are resumed/paused - just keep a reference to it like this:
YourActivity.java (could also be your Fragment)
private SubscriptionEventListener messageListener = new SubscriptionEventListener(){
#Override
public void onEvent(String channel, String event, String data) {
//TODO: do something with events
}
}
//Bind when the listener comes into the foreground:
#Override
protected void onResume() {
super.onResume();
((Global) getActivity().getApplication()).getChannel().bind("message", messageListener);
}
//Make sure to unbind the event listener!
#Override
protected void onPause() {
super.onPause();
((Global) getActivity().getApplication()).getChannel().unbind("message", messageListener);
}
I hope this helps :)

Simple SignalR Android Example Issue

I am basically trying to send a message from my android to my server and the server to send back a response to my android app. I followed THIS tutorial.
Just a simple exercise to introduce myself in to SignalR using Azure Web API and Android.
My Complete Server code in C#:
public class TestHub: Hub {
public void SendMessage(string name, string message) {
// Call the broadcastMessage method to update clients.
Clients.All.broadcastMessage(name, message);
}
public void SendClientMessage(CustomType obj) {
Clients.All.broadcastMessage("From Server", "Server got the message bro");
}
public class CustomType {
public string Name;
public int Id;
}
}
Complete Android Java code:
public class MainActivity extends AppCompatActivity {
Handler handler;
TextView statustext;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
handler = new Handler();
statustext = (TextView) findViewById(R.id.status);
Platform.loadPlatformComponent(new AndroidPlatformComponent());
// Change to the IP address and matching port of your SignalR server.
String host = "https://My-Service-name.azure-mobile.net/";
HubConnection connection = new HubConnection(host);
HubProxy hub = connection.createHubProxy("TestHub");
SignalRFuture < Void > awaitConnection = connection.start();
try {
awaitConnection.get();
} catch (InterruptedException e) {
} catch (ExecutionException e) {
}
hub.subscribe(this);
try {
hub.invoke("SendMessage", "Client", "Hello Server!").get();
hub.invoke("SendClientMessage",
new CustomType() {
{
Name = "Android Homie";
Id = 42;
}
}).get();
} catch (InterruptedException e) {
} catch (ExecutionException e) {
}
}
//I have no idea what the following method is for. Just followed the tutorial.. (blindly)
public void UpdateStatus(String status) {
final String fStatus = status;
handler.post(new Runnable() {
#Override
public void run() {
statustext.setText(fStatus);
}
});
}
public class CustomType {
public String Name;
public int Id;
}
}
Problems with this:
1. I get an exception:
java.util.concurrent.ExecutionException:
microsoft.aspnet.signalr.client.transport.NegotiationException: There
was a problem in the negotiation with the server
2. I feel like I haven't properly called the server from the Java code.
Should the URL be:
https://My-Service-name.azure-mobile.net/
or
https://My-Service-name.azure-mobile.net/api/signalr
Can someone clarify these doubts and help me set it up?

Categories

Resources