我试图使用在Android中实现WebSocket客户端的类.但是我收到以下错误:
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)
我正在使用的课程如下:
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); } }
该类在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:
Sdk: minSdkVersion 16
任何人都有任何想法,可能是什么问题?似乎一切都好!先感谢您.
我已经通过使用另一个处理websocket客户端的类解决了这个问题:
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(""); } }
对于任何有兴趣的人,我都使用了用PHP编写的Websocket-ChatServer:
'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)); }
为了启动websocket服务器,需要运行这样的控制台命令:php -q myserver.php