Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

What is a simple way to implement a websocket client in Android? Is the following example correct?

I was trying to use a class that implements a WebSocket client in Android. But I get the following error:

12-07 11:22:46.286 31579-31579/com.domain.wsocketchat W/System: ClassLoader referenced unknown path: /data/app/com.domain.wsocketchat-2/lib/arm 12-07 11:22:46.392 31579-31579/com.domain.wsocketchat W/System.err: an error occurred:java.net.SocketException: socket failed: EACCES (Permission denied) 

The class that I'm using follows:

import org.java_websocket.client.WebSocketClient; import org.java_websocket.drafts.Draft; import org.java_websocket.drafts.Draft_10; import org.java_websocket.handshake.ServerHandshake;  import java.net.URI;  public class EmptyClient extends WebSocketClient {     public EmptyClient(URI serverUri, Draft draft) {         super(serverUri, draft);     }      public EmptyClient(URI serverURI) {         super(serverURI);     }      @Override     public void onOpen(ServerHandshake handshakedata) {         System.out.println("new connection opened");     }      @Override     public void onClose(int code, String reason, boolean remote) {         System.out.println("closed with exit code " + code + " additional info: " + reason);     }      @Override     public void onMessage(String message) {         System.out.println("received message: " + message);     }      @Override     public void onError(Exception ex) {         System.err.println("an error occurred:" + ex);     } } 

The class is called within the onCreate():

WebSocketClient client = null; try {     client = new EmptyClient(new URI("ws://192.168.1.135:9000/server.php"), new Draft_10()); } catch (URISyntaxException e) {     e.printStackTrace(); } client.connect(); 

AndroidManifest:

<uses-permission android:name="android.permission.INTERNET" /> <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" /> <uses-permission android:name="android.permission.ACCESS_WIFI_STATE" /> 

Sdk: minSdkVersion 16

Anyone have any idea, what could be the problem? It seems everything allright! Thank you in advance.

like image 777
Kreshnik Avatar asked Dec 07 '15 10:12

Kreshnik


People also ask

How do you implement WebSockets?

webSockets are implemented as follows: Client makes HTTP request to server with "upgrade" header on the request. If server agrees to the upgrade, then client and server exchange some security credentials and the protocol on the existing TCP socket is switched from HTTP to webSocket.

What is a WebSocket example?

WebSocket Example A WebSocket is a standard bidirectional TCP socket between the client and the server. The socket starts out as a HTTP connection and then "Upgrades" to a TCP socket after a HTTP handshake. After the handshake, either side can send data.

Can we use WebSockets in Android?

The WebSocket protocol paved the way to a truly realtime web. At the time of writing this article, the Android SDK does not have native support for WebSockets. However, it relies on the Java Development Kit (JDK), which includes support for WebSockets as part of javax. websocket package.

When using WebSocket send () How do you know?

The only way to know the client received the webSocket message for sure is to have the client send your own custom message back to the server to indicate you received it and for you to wait for that message on the server. That's the ONLY end-to-end test that is guaranteed.


1 Answers

I already resolved the problem by using another class, that handles the websocket client:

    import android.app.Activity;     import android.app.Fragment;     import android.os.Build;     import android.os.Bundle;     import android.util.Log;     import android.view.LayoutInflater;     import android.view.Menu;     import android.view.MenuItem;     import android.view.View;     import android.view.ViewGroup;     import android.widget.EditText;     import android.widget.TextView;      import org.java_websocket.client.WebSocketClient;     import org.java_websocket.handshake.ServerHandshake;      import java.net.URI;     import java.net.URISyntaxException;      public class MainActivity extends Activity {         private WebSocketClient mWebSocketClient;          @Override         protected void onCreate(Bundle savedInstanceState) {             super.onCreate(savedInstanceState);             setContentView(R.layout.activity_main);              connectWebSocket();              if (savedInstanceState == null) {                 getFragmentManager().beginTransaction()                         .add(R.id.container, new PlaceholderFragment())                         .commit();             }         }           @Override         public boolean onCreateOptionsMenu(Menu menu) {              // Inflate the menu; this adds items to the action bar if it is present.             getMenuInflater().inflate(R.menu.main, menu);             return true;         }          @Override         public boolean onOptionsItemSelected(MenuItem item) {             // Handle action bar item clicks here. The action bar will             // automatically handle clicks on the Home/Up button, so long             // as you specify a parent activity in AndroidManifest.xml.             switch (item.getItemId()) {                 case R.id.action_settings:                     return true;             }             return super.onOptionsItemSelected(item);         }          /**          * A placeholder fragment containing a simple view.          */         public static class PlaceholderFragment extends Fragment {              public PlaceholderFragment() {             }              @Override             public View onCreateView(LayoutInflater inflater, ViewGroup container,                     Bundle savedInstanceState) {                 View rootView = inflater.inflate(R.layout.fragment_main, container, false);                 return rootView;             }         }          private void connectWebSocket() {             URI uri;             try {                 uri = new URI("ws://192.168.1.135:9000/");             } catch (URISyntaxException e) {                 e.printStackTrace();                 return;             }              mWebSocketClient = new WebSocketClient(uri) {                 @Override                 public void onOpen(ServerHandshake serverHandshake) {                     Log.i("Websocket", "Opened");                     mWebSocketClient.send("Hello from " + Build.MANUFACTURER + " " + Build.MODEL);                 }                  @Override                 public void onMessage(String s) {                     final String message = s;                     runOnUiThread(new Runnable() {                         @Override                         public void run() {                             TextView textView = (TextView)findViewById(R.id.messages);                             textView.setText(textView.getText() + "\n" + message);                         }                     });                 }                  @Override                 public void onClose(int i, String s, boolean b) {                     Log.i("Websocket", "Closed " + s);                 }                  @Override                 public void onError(Exception e) {                     Log.i("Websocket", "Error " + e.getMessage());                 }             };             mWebSocketClient.connect();         }          public void sendMessage(View view) {             EditText editText = (EditText)findViewById(R.id.message);             mWebSocketClient.send(editText.getText().toString());             editText.setText("");         }     } 

For anyone that is interested, I've used a Websocket-ChatServer written in PHP:

<?php $r = $_SERVER['SERVER_ADDR']; if($r=="::1") $r="localhost";  $host = $r; //'localhost'; //host $port = '9000'; //port $null = NULL; //null var  //Create TCP/IP sream socket $socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP); //reuseable port socket_set_option($socket, SOL_SOCKET, SO_REUSEADDR, 1);  //bind socket to specified host socket_bind($socket, 0, $port);  //listen to port socket_listen($socket);  //create & add listning socket to the list $clients = array($socket);  //start endless loop, so that our script doesn't stop while (true) {     //manage multipal connections     $changed = $clients;     //returns the socket resources in $changed array     socket_select($changed, $null, $null, 0, 10);      //check for new socket     if (in_array($socket, $changed)) {         $socket_new = socket_accept($socket); //accpet new socket         $clients[] = $socket_new; //add socket to client array          $header = socket_read($socket_new, 1024); //read data sent by the socket         perform_handshaking($header, $socket_new, $host, $port); //perform websocket handshake          socket_getpeername($socket_new, $ip); //get ip address of connected socket         $response = mask(json_encode(array('type'=>'system', 'message'=>$ip.' connected'))); //prepare json data         send_message($response); //notify all users about new connection          //make room for new socket         $found_socket = array_search($socket, $changed);         unset($changed[$found_socket]);     }      //loop through all connected sockets     foreach ($changed as $changed_socket) {           //check for any incomming data         while(socket_recv($changed_socket, $buf, 1024, 0) >= 1)         {             $received_text = unmask($buf); //unmask data             $tst_msg = json_decode($received_text); //json decode              $user_name = $tst_msg->name; //sender name             $user_message = $tst_msg->message; //message text             $user_color = $tst_msg->color; //color              //prepare data to be sent to client             $response_text = mask(json_encode(array('type'=>'usermsg', 'name'=>$user_name, 'message'=>$user_message, 'color'=>$user_color)));             send_message($response_text); //send data             break 2; //exist this loop         }          $buf = @socket_read($changed_socket, 1024, PHP_NORMAL_READ);         if ($buf === false) { // check disconnected client             // remove client for $clients array             $found_socket = array_search($changed_socket, $clients);             socket_getpeername($changed_socket, $ip);             unset($clients[$found_socket]);              //notify all users about disconnected connection             $response = mask(json_encode(array('type'=>'system', 'message'=>$ip.' disconnected')));             send_message($response);         }     } } // close the listening socket socket_close($sock);  function send_message($msg) {     global $clients;     foreach($clients as $changed_socket)     {         @socket_write($changed_socket,$msg,strlen($msg));     }     return true; }   //Unmask incoming framed message function unmask($text) {     $length = ord($text[1]) & 127;     if($length == 126) {         $masks = substr($text, 4, 4);         $data = substr($text, 8);     }     elseif($length == 127) {         $masks = substr($text, 10, 4);         $data = substr($text, 14);     }     else {         $masks = substr($text, 2, 4);         $data = substr($text, 6);     }     $text = "";     for ($i = 0; $i < strlen($data); ++$i) {         $text .= $data[$i] ^ $masks[$i%4];     }     return $text; }  //Encode message for transfer to client. function mask($text) {     $b1 = 0x80 | (0x1 & 0x0f);     $length = strlen($text);      if($length <= 125)         $header = pack('CC', $b1, $length);     elseif($length > 125 && $length < 65536)         $header = pack('CCn', $b1, 126, $length);     elseif($length >= 65536)         $header = pack('CCNN', $b1, 127, $length);     return $header.$text; }  //handshake new client. function perform_handshaking($receved_header,$client_conn, $host, $port) {     $headers = array();     $lines = preg_split("/\r\n/", $receved_header);     foreach($lines as $line)     {         $line = chop($line);         if(preg_match('/\A(\S+): (.*)\z/', $line, $matches))         {             $headers[$matches[1]] = $matches[2];         }     }      $secKey = $headers['Sec-WebSocket-Key'];     $secAccept = base64_encode(pack('H*', sha1($secKey . '258EAFA5-E914-47DA-95CA-C5AB0DC85B11')));     //hand shaking header     $upgrade  = "HTTP/1.1 101 Web Socket Protocol Handshake\r\n" .     "Upgrade: websocket\r\n" .     "Connection: Upgrade\r\n" .     "WebSocket-Origin: $host\r\n" .     "WebSocket-Location: ws://$host:$port/demo/shout.php\r\n".     "Sec-WebSocket-Accept:$secAccept\r\n\r\n";     socket_write($client_conn,$upgrade,strlen($upgrade)); } 

In order to start the websocket server it's needed to run a console command like this: php -q myserver.php

like image 200
Kreshnik Avatar answered Oct 02 '22 13:10

Kreshnik