I am working on websocket communication with Autobahn.
On the main.class of my app, I set to call 'connect()' when users click a button.
// Toggle Button event
tButton = (ToggleButton) findViewById(R.id.toggleButton1);
tButton.setOnCheckedChangeListener(new OnCheckedChangeListener() {
#Override
public void onCheckedChanged(CompoundButton buttonView,
boolean isChecked) {
if(isChecked){
}else{
}
}
});
And after that, there is MyOffers.class, and if this class is accessed,
MyOffers_Fragment class is produced four times automatically, because MyOffers.class contains 'carousel view' and there are four products.
On 'MyOffers_Fragment' class, when users click one of the image of products, message should be sent.
if (pos == 0) {
product_photo.setImageResource(R.drawable.myoffers_0);
product_photo.setOnClickListener(new ImageButton.OnClickListener(){
public void onClick(View v){
String id = "Product0";
Log.d(TAG, "Current product is : " + id);
A.sendMessage(id);
}
});
}
But 'mConnection.sendTextMessage(id1);' this line makes 'NullPointerException' error.
There is a class 'Websocket_Connector.class'
public class WebSocket_Connector {
private static final String TAG = "ECHOCLIENT";
public final WebSocketConnection mConnection = new WebSocketConnection();
public void connect(final String wsuri) {
Log.d(TAG, "Connecting to: " + wsuri);
try {
mConnection.connect(wsuri, new WebSocketHandler() {
#Override
public void onOpen() {
Log.d(TAG, "Status: Connected to " + wsuri );
Log.d(TAG, "Connection successful!\n");
}
#Override
public void onTextMessage(String payload) {
Log.d(TAG, "Got echo: " + payload);
}
#Override
public void onClose(int code, String reason) {
Log.d(TAG, "Connection closed.");
}
});
} catch (WebSocketException e) {
Log.d(TAG, e.toString());
}
public void sendMessage(String message) {
connect("ws://192.168.x.xxx:xxxx");
mConnection.sendTextMessage(message);
}
}
I called 'connect()' in the main page class, and after that try to send message.
But, it's not working..Can you please help me out?
public class WebSocket_Connector {
private static final String TAG = "ECHOCLIENT";
public final WebSocketConnection mConnection = new WebSocketConnection();
private String tmpString = "";
public void connect(final String wsuri) {
Log.d(TAG, "Connecting to: " + wsuri);
try {
mConnection.connect(wsuri, new WebSocketHandler() {
#Override
public void onOpen() {
Log.d(TAG, "Status: Connected to " + wsuri );
Log.d(TAG, "Connection successful!\n");
mConnection.sendTextMessage(tmpString);
tmpString = "";
}
#Override
public void onTextMessage(String payload) {
Log.d(TAG, "Got echo: " + payload);
}
#Override
public void onClose(int code, String reason) {
Log.d(TAG, "Connection closed.");
}
});
} catch (WebSocketException e) {
Log.d(TAG, e.toString());
}
public void sendMessage(String message) {
if (mConnection.isConnected())
mConnection.sendTextMessage(message);
else {
tmpString = message;
connect("ws://192.168.x.xxx:xxxx");
}
}
}
Related
I have created a private channel, and joined the channel. I like to invite another user to join that channel and chat. To be clear, this should be a chat between two members only.
public class MainActivity extends AppCompatActivity {
/*
Change this URL to match the token URL for your Twilio Function
*/
final static String SERVER_TOKEN_URL = "https://example.com/twilio/token/";
final static String MY_CHANNEL_NAME = "testchat1234567810";
final static String TAG = "TwilioChat";
// Update this identity for each individual user, for instance after they login
private String mIdentity ;
private String accessToken;
private RecyclerView mMessagesRecyclerView;
private MessagesAdapter mMessagesAdapter;
private ArrayList<Message> mMessages = new ArrayList<>();
private EditText mWriteMessageEditText;
private Button mSendChatMessageButton;
private ChatClient mChatClient;
private Channel mGeneralChannel;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
mMessagesRecyclerView = (RecyclerView) findViewById(R.id.messagesRecyclerView);
LinearLayoutManager layoutManager = new LinearLayoutManager(this);
// for a chat app, show latest at the bottom
layoutManager.setStackFromEnd(true);
mMessagesRecyclerView.setLayoutManager(layoutManager);
mMessagesAdapter = new MessagesAdapter();
mMessagesRecyclerView.setAdapter(mMessagesAdapter);
mWriteMessageEditText = (EditText) findViewById(R.id.writeMessageEditText);
mSendChatMessageButton = (Button) findViewById(R.id.sendChatMessageButton);
mSendChatMessageButton.setOnClickListener(new View.OnClickListener() {
#Override
public void onClick(View view) {
createOrJoinChannel();
if (mGeneralChannel != null) {
String messageBody = mWriteMessageEditText.getText().toString();
Message.Options options = Message.options().withBody(messageBody);
// mGeneralChannel.getMembers().add();
Members members = mGeneralChannel.getMembers();
if (members != null) {
ArrayList<Member> list = (ArrayList<Member>) members.getMembersList();
for (int i = 0; i < list.size(); i++) {
Log.i(TAG, "member " + i + list.get(i).getIdentity());
}
}
mGeneralChannel.getMembers().inviteByIdentity("user1#gmail.com", new StatusListener() {
#Override
public void onSuccess() {
Log.d(TAG, "User Invited on send!");
}
#Override
public void onError(ErrorInfo errorInfo) {
Log.i(TAG, "chats: inviting user" + errorInfo.getMessage());
}
});
mGeneralChannel.getMembersCount(new CallbackListener<Long>() {
#Override
public void onSuccess(Long aLong) {
Log.e("member count >>", aLong + "");
}
});
mGeneralChannel.getMessages().sendMessage(options, new CallbackListener<Message>() {
#Override
public void onSuccess(Message message) {
MainActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
Log.d(TAG, "Message created");
// need to modify user interface elements on the UI thread
mWriteMessageEditText.setText("");
}
});
}
});
}
}
});
retrieveAccessTokenfromServer();
}
private void retrieveAccessTokenfromServer() {
String deviceId = Settings.Secure.getString(getContentResolver(), Settings.Secure.ANDROID_ID);
Log.e("deviceid >>",deviceId);
String tokenURL = SERVER_TOKEN_URL + deviceId;
Ion.with(this)
.load(tokenURL)
.asJsonObject()
.setCallback(new FutureCallback<JsonObject>() {
#Override
public void onCompleted(Exception e, JsonObject result) {
Log.e("result >>", result.toString() + "");
if (e == null) {
mIdentity = result.get("identity").getAsString();
accessToken = result.get("token").getAsString();
setTitle(mIdentity);
ChatClient.Properties.Builder builder = new ChatClient.Properties.Builder();
// ChatClient.setLogLevel(Log.VERBOSE);
ChatClient.Properties props = builder.createProperties();
ChatClient.create(MainActivity.this, accessToken, props, mChatClientCallback);
} else {
Toast.makeText(MainActivity.this,
R.string.error_retrieving_access_token, Toast.LENGTH_SHORT)
.show();
}
}
});
}
private CallbackListener<ChatClient> mChatClientCallback =
new CallbackListener<ChatClient>() {
#Override
public void onSuccess(ChatClient chatClient) {
mChatClient = chatClient;
// createOrJoinChannel();
// loadChannels();
Log.d(TAG, "Success creating Twilio Chat Client");
}
#Override
public void onError(ErrorInfo errorInfo) {
Log.e(TAG, "Error creating Twilio Chat Client: " + errorInfo.getMessage());
}
};
private void createOrJoinChannel() {
//Only SID or unique name of channel can be supplied as parameter
mChatClient.getChannels().getChannel(MY_CHANNEL_NAME, new CallbackListener<Channel>() {
#Override
public void onSuccess(Channel channel) {
if (channel != null) {
if (channel.getStatus() == Channel.ChannelStatus.JOINED) {
// already in the channel, load the messages
mGeneralChannel = channel;
mGeneralChannel.addListener(mDefaultChannelListener);
} else if (channel.getStatus() == Channel.ChannelStatus.NOT_PARTICIPATING) {
// already in the channel, load the messages
mGeneralChannel = channel;
mGeneralChannel.addListener(mDefaultChannelListener);
} else {
// join the channel
joinChannel(channel);
}
} else {
Log.i(TAG, "Error occurred in getting channel");
}
}
#Override
public void onError(ErrorInfo errorInfo) {
Log.i(TAG, "Error retrieving channel: " + errorInfo.getMessage());
createChannel();
}
});
}
private void joinChannel(final Channel channel) {
Log.i(TAG, "inside join channel" + channel.getUniqueName());
Log.i(TAG, "channel status: " + channel.getStatus());
Members members = channel.getMembers();
if (members != null) {
ArrayList<Member> list = (ArrayList<Member>) members.getMembersList();
for (int i = 0; i < list.size(); i++) {
Log.i(TAG, "member " + i + list.get(i).getIdentity());
}
} else {
Log.i(TAG, "null object"); //Getting this even when I get
//"Member already exists" error
}
channel.join(new StatusListener() {
#Override
public void onSuccess() {
mGeneralChannel = channel;
mGeneralChannel.addListener(mDefaultChannelListener);
}
#Override
public void onError(ErrorInfo errorInfo) {
//Error joining channel: Member already exists
Log.i(TAG, "Error joining channel: " + errorInfo.getMessage());
}
});
}
private void createChannel() {
mChatClient.getChannels().createChannel(MY_CHANNEL_NAME,
Channel.ChannelType.PUBLIC, new CallbackListener<Channel>() {
#Override
public void onSuccess(final Channel channel) {
if (channel != null) {
/* channel.getMembersCount(new CallbackListener<Long>() {
#Override
public void onSuccess(Long aLong) {
Log.e("member count >>",aLong+"");
}
});*/
channel.getMembers().inviteByIdentity("user1#gmail.com", new StatusListener() {
#Override
public void onSuccess() {
Log.d(TAG, "User Invited!");
}
#Override
public void onError(ErrorInfo errorInfo) {
Log.i(TAG, "chats: inviting user" + errorInfo.getMessage());
}
});
channel.join(new StatusListener() {
#Override
public void onSuccess() {
}
});
setUniqueNameAndJoin(channel);
}
}
#Override
public void onError(ErrorInfo errorInfo) {
Log.i(TAG, "chats: " + "Unique name could not be set: " + errorInfo.getMessage());
}
});
}
private void setUniqueNameAndJoin(final Channel channel) {
channel.setUniqueName(MY_CHANNEL_NAME, new StatusListener() {
#Override
public void onSuccess() {
Log.i(TAG, "channel with unique name created " + channel.getUniqueName());
joinChannel(channel);
}
#Override
public void onError(ErrorInfo errorInfo) {
super.onError(errorInfo);
}
});
}
private ChannelListener mDefaultChannelListener = new ChannelListener() {
#Override
public void onMessageAdded(final Message message) {
Log.d(TAG, "Message added");
MainActivity.this.runOnUiThread(new Runnable() {
#Override
public void run() {
// need to modify user interface elements on the UI thread
mMessages.add(message);
mMessagesAdapter.notifyDataSetChanged();
}
});
}
#Override
public void onMessageUpdated(Message message, Message.UpdateReason updateReason) {
Log.d(TAG, "Message updated: " + message.getMessageBody());
}
#Override
public void onMessageDeleted(Message message) {
Log.d(TAG, "Message deleted");
}
#Override
public void onMemberAdded(Member member) {
Log.d(TAG, "Member added: " + member.getIdentity());
}
#Override
public void onMemberUpdated(Member member, Member.UpdateReason updateReason) {
Log.d(TAG, "Member updated: " + member.getIdentity());
}
#Override
public void onMemberDeleted(Member member) {
Log.d(TAG, "Member deleted: " + member.getIdentity());
}
#Override
public void onTypingStarted(Channel channel, Member member) {
Log.d(TAG, "Started Typing: " + member.getIdentity());
}
#Override
public void onTypingEnded(Channel channel, Member member) {
Log.d(TAG, "Ended Typing: " + member.getIdentity());
}
#Override
public void onSynchronizationChanged(Channel channel) {
}
};
class MessagesAdapter extends RecyclerView.Adapter<MessagesAdapter.ViewHolder> {
class ViewHolder extends RecyclerView.ViewHolder {
public TextView mMessageTextView;
public ViewHolder(TextView textView) {
super(textView);
mMessageTextView = textView;
}
}
public MessagesAdapter() {
}
#Override
public MessagesAdapter
.ViewHolder onCreateViewHolder(ViewGroup parent,
int viewType) {
TextView messageTextView = (TextView) LayoutInflater.from(parent.getContext())
.inflate(R.layout.message_text_view, parent, false);
return new ViewHolder(messageTextView);
}
#Override
public void onBindViewHolder(ViewHolder holder, int position) {
Message message = mMessages.get(position);
String messageText = String.format("%s: %s", message.getAuthor(), message.getMessageBody());
holder.mMessageTextView.setText(messageText);
}
#Override
public int getItemCount() {
return mMessages.size();
}
}
}
And also, I need to accept the invite. How it can be done?
How to playback video stream from web socket address like :
ws://somevideserver.net:8410/5b03a7aad01502281a39?
I tried using WebSocketClient and successfully connect to port, but how to retrieve stream and send it to player?
URI uri;
try {
uri = new URI(stremURL);
} catch (URISyntaxException e) {
e.printStackTrace();
return;
}
mWebSocketClient = new WebSocketClient(uri) {
#Override
public void onOpen(ServerHandshake serverHandshake) {
Log.d(TAG, "[getStreamURL] = "+"Opened");
// mWebSocketClient.send("Hello from " + Build.MANUFACTURER + " " + Build.MODEL);
startStreaming();
}
#Override
public void onMessage(String s) {
final String message = s;
runOnUiThread(new Runnable() {
#Override
public void run() {
Log.d(TAG, "[getStreamURL] message = "+message);
}
});
}
private void runOnUiThread(Runnable websocket) {
}
#Override
public void onClose(int i, String s, boolean b) {
Log.d(TAG, "[getStreamURL] = "+"Closed");
}
#Override
public void onError(Exception e) {
Log.d(TAG, "[getStreamURL] = "+"Error");
}
};
mWebSocketClient.connect();
I am currently using
https://github.com/NaikSoftware/StompProtocolAndroid
to connect websocket using STOMP. I have a simple implementation as
public class TestActivity extends AppCompatActivity {
private StompClient mStompCLient;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_test);
ButterKnife.bind(this);
setSupportActionBar(toolbar);
mStompCLient = Stomp.over(WebSocket.class, BASE_URL);
mStompCLient.topic("/topic/online/" + mSharedPreferences.getPrivateKey()).subscribe(new Subscriber<StompMessage>() {
#Override
public void onCompleted() {
Log.i(TAG, "/topic/online/ onCompleted: ");
}
#Override
public void onError(Throwable e) {
Log.i(TAG, "/topic/online/ onError: " + e.getMessage());
}
#Override
public void onNext(StompMessage stompMessage) {
Log.d(TAG, "/topic/online/ onNext: " + stompMessage.getPayload());
String content = "";
JSONObject jsonResponse = null;
try {
jsonResponse = new JSONObject(stompMessage.getPayload());
content = jsonResponse.getString("uri");
} catch (JSONException e) {
e.printStackTrace();
}
listenToUpdatesFromFinalUri(content);
}
});
mStompCLient.lifecycle().subscribe(lifecycleEvent -> {
Log.i(TAG, "onCreate: " + lifecycleEvent.getMessage());
switch (lifecycleEvent.getType()) {
case OPENED:
Log.d(TAG, "Stomp connection opened");
break;
case ERROR:
Log.e(TAG, "Error", lifecycleEvent.getException());
break;
case CLOSED:
Log.d(TAG, "Stomp connection closed : " + lifecycleEvent.toString() + " :msg: " + lifecycleEvent.getMessage() + " :escep: " + lifecycleEvent.getException() + " :headers: " + lifecycleEvent.getHandshakeResponseHeaders() + " :type: " + lifecycleEvent.getType());
break;
}
});
mStompCLient.connect();
}
private void listenToUpdatesFromFinalUri(String content) {
mStompCLient.topic(content).subscribe(new Subscriber<StompMessage>() {
#Override
public void onCompleted() {
Log.i(TAG," onCompleted: ");
}
#Override
public void onError(Throwable e) {
Log.i(TAG, " onError: " + e.getMessage());
}
#Override
public void onNext(StompMessage stompMessage) {
Log.d(TAG, " onNext: " + stompMessage.getPayload());
}
});
}
#Override
protected void onStop() {
super.onStop();
disconnectStomp();
}
private void disconnectStomp() {
mStompCLient.disconnect();
}
}
Here I am trying to listen to the new subscription channel sent by the server after connection is established. It works if the subscribe() is called before the connect is called. But the final uri/subscription channel subscribed in listenToUpdatesFromFinalUri() function is not static so I need can't add subscription before the connect. I am currently unable to get response for the final uri/subscription. Any help is appreciated.
The issue has been solved in the new version 1.1.6
I'm implement Autobahn to connnect to a server through WebSockets. When I hit connect, it opens the socket correctly and logs that socket is opened. I then try to send a request to the server which is simply {"request":"getSoftwareVersion"} , when the server receives this, it should send back the software version in a JSON object, the trouble is, that onMessage is never hit. Here is my code:
public class AutoBahnConnectRequest extends Request{
private static WebSocketConnection mAutoBahnConnection;
private String mSocketHostAddress;
private final static String m_TAG = AutoBahnConnectRequest.class.getSimpleName();
public AutoBahnConnectRequest(String SocketHostAddress){
this.mAutoBahnConnection = new WebSocketConnection();
this.mSocketHostAddress = SocketHostAddress;
}
#Override
protected Void doInBackground(Void... params){
try {
mAutoBahnConnection.connect(mSocketHostAddress, new WebSocketHandler(){
#Override
public void onOpen() {
String requestSoftware = "{\"request\":\"getSoftwareVersion\"}";
Log.i(m_TAG, requestSoftware);
Log.i(m_TAG, "Status: Connected to " + mSocketHostAddress);
mAutoBahnConnection.sendTextMessage(requestSoftware);
}
#Override
public void onTextMessage(String payload) {
Log.i(m_TAG, "Got echo: " + payload);
}
#Override
public void onClose(int code, String reason) {
Log.i(m_TAG, "Connection lost."+ reason);
}
});
} catch (WebSocketException e) {
Log.d(m_TAG, e.toString());
}
return null;
}
}
This has been implemented with a html client like so (not with autobahn):
function getSoftwareVersion() {
socket_di.send('{"request":"getSoftwareVersion"}');
}
and the onMessage receives the data. Can someone please tell me if I'm doing something wrong here?
Thank you.
I have figured out my issue regarding this. The WebSocket connection required a protocol and options to be added. So I changed this:
mAutoBahnConnection.connect(mSocketHostAddress, new WebSocketHandler(){
#Override
public void onOpen() {
String requestSoftware = "{\"request\":\"getSoftwareVersion\"}";
Log.i(m_TAG, requestSoftware);
Log.i(m_TAG, "Status: Connected to " + mSocketHostAddress);
mAutoBahnConnection.sendTextMessage(requestSoftware);
}
#Override
public void onTextMessage(String payload) {
Log.i(m_TAG, "Got echo: " + payload);
}
#Override
public void onClose(int code, String reason) {
Log.i(m_TAG, "Connection lost."+ reason);
}
});
} catch (WebSocketException e) {
Log.d(m_TAG, e.toString());
}
to this:
mAutoBahnConnection.connect(mSocketHostAddress,new String[]{"this is my protocol"} ,new WebSocketHandler(){
#Override
public void onOpen() {
String requestSoftware = "{\"request\":\"getSoftwareVersion\"}";
Log.i(m_TAG, requestSoftware);
Log.i(m_TAG, "Status: Connected to " + mSocketHostAddress);
mAutoBahnConnection.sendTextMessage(requestSoftware);
}
#Override
public void onTextMessage(String payload) {
Log.i(m_TAG, "Got echo: " + payload);
}
#Override
public void onRawTextMessage(byte[] payload) {
try {
rawText = new String(payload, "UTF-8");
Log.i(m_TAG, "ON RAW TEXT");
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
}
#Override
public void onBinaryMessage(byte[] payload) {
Log.i(m_TAG, "ON BINARY MESSAGE");
}
#Override
public void onClose(int code, String reason) {
Log.i(m_TAG, "Connection lost."+ reason);
}
}, options);
} catch (WebSocketException e) {
Log.d(m_TAG, e.toString());
}
Client side code:
private void startPolling() {
final String wsuri = MainAsync.WEB_SOCKET_HOST_WS+"/game";
try {
mConnection.connect(wsuri, new WebSocketHandler() {
#Override
public void onOpen() {
Log.d(TAG, "Status: Connected to " + wsuri);
int role = mAccMeth.loadId(getApplicationContext());
mConnection.sendTextMessage(String.valueOf(role));
}
#Override
public void onTextMessage(String payload) {
Log.d(TAG, "Got echo: " + payload);
}
#Override
public void onClose(int code, String reason) {
Log.d(TAG, "Connection lost.");
}
});
} catch (WebSocketException e) {
Log.d(TAG, e.toString());
}
}
Server side realisation:
#ServerEndpoint(value="/game",configurator = ServletConfig.class)
public class WebSocketPollingCoordinates {
EndpointConfig endConfig;
#OnMessage
public void receiveMessage(String message,final Session session){
HttpSession httpSession = (HttpSession) endConfig.getUserProperties().get("httpSession");
//at this line i get NullpointerException
final ServletContext sercntxt = (ServletContext)httpSession.getServletContext();
}
#OnOpen
public void onOpen(Session sn, EndpointConfig ec) {
System.out.println("onOpen");
this.endConfig = ec;
}
#OnError
public void error(Session session, Throwable t) {
t.printStackTrace();
}
And WebSocket Config class:
public class ServletConfig extends Configurator{
#Override
public void modifyHandshake(ServerEndpointConfig config, HandshakeRequest request, HandshakeResponse response) {
HttpSession httpSession = (HttpSession) request.getHttpSession();
if(httpSession==null || config==null){
if(httpSession==null)
System.out.println("httpSession==null");
if(config==null)
System.out.println("config==null");
return;
}
config.getUserProperties().put("httpSession", httpSession);
}
}
I'm always getting next out: http session == null. Where is the error? I need to get httpSession, to call void httpSession.getServletContext();