Android套接字未连接到服务器

时间:2017-09-08 11:47:01

标签: android node.js sockets

这里我有一个与android套接字和服务器之间的连接有关的查询。我关注https://socket.io/blog/native-socket-io-and-android/并发现它工作正常,因此我将本地服务器URL替换为教程中的URL。但在这里,我总是遇到connection failed or disconnection错误。这是我的应用程序类,以便进一步澄清。

public class ChatApplication extends Application {

private Socket mSocket;

{
    try {
        IO.Options options = new IO.Options();
        options.forceNew = true;
        options.reconnection = true;
        JSONObject jsonObject = new JSONObject();
        try {
            jsonObject.put("uid", 1);
            jsonObject.put("usid", 6847);
            options.query = jsonObject.toString();

        } catch (JSONException e) {
            e.printStackTrace();
        }
        Log.e("JSON", jsonObject.toString());
        Log.e("OPTIONS", options.toString());
        mSocket = IO.socket(Constants.CHAT_SERVER_URL, options);
    } catch (URISyntaxException e) {
        throw new RuntimeException(e);
    }
}

public Socket getSocket() {
    return mSocket;
}
}

片段的代码如下。每当我使用本地服务器时,它都会一直调用onDisconnect()

public class MainFragment extends Fragment {
private static final String TAG = "MainFragment";
private static final int REQUEST_LOGIN = 0;
private static final int TYPING_TIMER_LENGTH = 600;
private RecyclerView mMessagesView;
private EditText mInputMessageView;
private List<Message> mMessages = new ArrayList<Message>();
private RecyclerView.Adapter mAdapter;
private boolean mTyping = false;
private Handler mTypingHandler = new Handler();
private String mUsername;
private Socket mSocket;
private Boolean isConnected = true;
private Emitter.Listener onConnect = new Emitter.Listener() {
    @Override
    public void call(Object... args) {
        getActivity().runOnUiThread(new Runnable() {
            @Override
            public void run() {
                if (!isConnected) {
                    if (null != mUsername)
                        mSocket.emit("add user", mUsername);
                    Toast.makeText(getActivity().getApplicationContext(),
                            R.string.connect, Toast.LENGTH_LONG).show();
                    isConnected = true;
                }
            }
        });
    }
};
private Emitter.Listener onDisconnect = new Emitter.Listener() {
    @Override
    public void call(Object... args) {
        getActivity().runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Log.i(TAG, "diconnected");
                isConnected = false;
                Toast.makeText(getActivity().getApplicationContext(),
                        R.string.disconnect, Toast.LENGTH_LONG).show();
            }
        });
    }
};
private Emitter.Listener onConnectError = new Emitter.Listener() {
    @Override
    public void call(Object... args) {
        getActivity().runOnUiThread(new Runnable() {
            @Override
            public void run() {
                Log.e(TAG, "Error connecting");
                Toast.makeText(getActivity().getApplicationContext(),
                        R.string.error_connect, Toast.LENGTH_LONG).show();
            }
        });
    }
};
private Emitter.Listener onNewMessage = new Emitter.Listener() {
    @Override
    public void call(final Object... args) {
        getActivity().runOnUiThread(new Runnable() {
            @Override
            public void run() {
                JSONObject data = (JSONObject) args[0];
                String username;
                String message;
                try {
                    username = data.getString("username");
                    message = data.getString("message");
                } catch (JSONException e) {
                    Log.e(TAG, e.getMessage());
                    return;
                }

                removeTyping(username);
                addMessage(username, message);
            }
        });
    }
};
private Emitter.Listener onUserJoined = new Emitter.Listener() {
    @Override
    public void call(final Object... args) {
        getActivity().runOnUiThread(new Runnable() {
            @Override
            public void run() {
                JSONObject data = (JSONObject) args[0];
                String username;
                int numUsers;
                try {
                    username = data.getString("username");
                    numUsers = data.getInt("numUsers");
                } catch (JSONException e) {
                    Log.e(TAG, e.getMessage());
                    return;
                }

                addLog(getResources().getString(R.string.message_user_joined, username));
                addParticipantsLog(numUsers);
            }
        });
    }
};
private Emitter.Listener onUserLeft = new Emitter.Listener() {
    @Override
    public void call(final Object... args) {
        getActivity().runOnUiThread(new Runnable() {
            @Override
            public void run() {
                JSONObject data = (JSONObject) args[0];
                String username;
                int numUsers;
                try {
                    username = data.getString("username");
                    numUsers = data.getInt("numUsers");
                } catch (JSONException e) {
                    Log.e(TAG, e.getMessage());
                    return;
                }

                addLog(getResources().getString(R.string.message_user_left, username));
                addParticipantsLog(numUsers);
                removeTyping(username);
            }
        });
    }
};
private Emitter.Listener onTyping = new Emitter.Listener() {
    @Override
    public void call(final Object... args) {
        getActivity().runOnUiThread(new Runnable() {
            @Override
            public void run() {
                JSONObject data = (JSONObject) args[0];
                String username;
                try {
                    username = data.getString("username");
                } catch (JSONException e) {
                    Log.e(TAG, e.getMessage());
                    return;
                }
                addTyping(username);
            }
        });
    }
};
private Emitter.Listener onStopTyping = new Emitter.Listener() {
    @Override
    public void call(final Object... args) {
        getActivity().runOnUiThread(new Runnable() {
            @Override
            public void run() {
                JSONObject data = (JSONObject) args[0];
                String username;
                try {
                    username = data.getString("username");
                } catch (JSONException e) {
                    Log.e(TAG, e.getMessage());
                    return;
                }
                removeTyping(username);
            }
        });
    }
};
private Runnable onTypingTimeout = new Runnable() {
    @Override
    public void run() {
        if (!mTyping) return;
        mTyping = false;
        mSocket.emit("stop typing");
    }
};

public MainFragment() {
    super();
}

// This event fires 1st, before creation of fragment or any views
// The onAttach method is called when the Fragment instance is associated with an Activity.
// This does not mean the Activity is fully initialized.
@Override
public void onAttach(Context context) {
    super.onAttach(context);
    mAdapter = new MessageAdapter(context, mMessages);
    if (context instanceof Activity) {
        //this.listener = (MainActivity) context;
    }
}

@Override
public void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);

    setHasOptionsMenu(true);

    ChatApplication app = (ChatApplication) getActivity().getApplication();
    mSocket = app.getSocket();
    mSocket.on(Socket.EVENT_CONNECT, onConnect);
    mSocket.on(Socket.EVENT_DISCONNECT, onDisconnect);
    mSocket.on(Socket.EVENT_CONNECT_ERROR, onConnectError);
    mSocket.on(Socket.EVENT_CONNECT_TIMEOUT, onConnectError);
    mSocket.on("new message", onNewMessage);
    mSocket.on("user joined", onUserJoined);
    mSocket.on("user left", onUserLeft);
    mSocket.on("typing", onTyping);
    mSocket.on("stop typing", onStopTyping);
    mSocket.connect();

    startSignIn();
}

@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container,
                         Bundle savedInstanceState) {
    return inflater.inflate(R.layout.fragment_main, container, false);
}

@Override
public void onDestroy() {
    super.onDestroy();

    mSocket.disconnect();

    mSocket.off(Socket.EVENT_CONNECT, onConnect);
    mSocket.off(Socket.EVENT_DISCONNECT, onDisconnect);
    mSocket.off(Socket.EVENT_CONNECT_ERROR, onConnectError);
    mSocket.off(Socket.EVENT_CONNECT_TIMEOUT, onConnectError);
    mSocket.off("new message", onNewMessage);
    mSocket.off("user joined", onUserJoined);
    mSocket.off("user left", onUserLeft);
    mSocket.off("typing", onTyping);
    mSocket.off("stop typing", onStopTyping);
}

@Override
public void onViewCreated(View view, Bundle savedInstanceState) {
    super.onViewCreated(view, savedInstanceState);

    mMessagesView = (RecyclerView) view.findViewById(R.id.messages);
    mMessagesView.setLayoutManager(new LinearLayoutManager(getActivity()));
    mMessagesView.setAdapter(mAdapter);

    mInputMessageView = (EditText) view.findViewById(R.id.message_input);
    mInputMessageView.setOnEditorActionListener(new TextView.OnEditorActionListener() {
        @Override
        public boolean onEditorAction(TextView v, int id, KeyEvent event) {
            if (id == R.id.send || id == EditorInfo.IME_NULL) {
                attemptSend();
                return true;
            }
            return false;
        }
    });
    mInputMessageView.addTextChangedListener(new TextWatcher() {
        @Override
        public void beforeTextChanged(CharSequence s, int start, int count, int after) {
        }

        @Override
        public void onTextChanged(CharSequence s, int start, int before, int count) {
            if (null == mUsername) return;
            if (!mSocket.connected()) return;

            if (!mTyping) {
                mTyping = true;
                mSocket.emit("typing");
            }

            mTypingHandler.removeCallbacks(onTypingTimeout);
            mTypingHandler.postDelayed(onTypingTimeout, TYPING_TIMER_LENGTH);
        }

        @Override
        public void afterTextChanged(Editable s) {
        }
    });

    ImageButton sendButton = (ImageButton) view.findViewById(R.id.send_button);
    sendButton.setOnClickListener(new View.OnClickListener() {
        @Override
        public void onClick(View v) {
            attemptSend();
        }
    });
}

@Override
public void onActivityResult(int requestCode, int resultCode, Intent data) {
    super.onActivityResult(requestCode, resultCode, data);
    if (Activity.RESULT_OK != resultCode) {
        getActivity().finish();
        return;
    }

    mUsername = data.getStringExtra("username");
    int numUsers = data.getIntExtra("numUsers", 1);

    addLog(getResources().getString(R.string.message_welcome));
    addParticipantsLog(numUsers);
}

@Override
public void onCreateOptionsMenu(Menu menu, MenuInflater inflater) {
    // Inflate the menu; this adds items to the action bar if it is present.
    inflater.inflate(R.menu.menu_main, menu);
}

@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.
    int id = item.getItemId();

    //noinspection SimplifiableIfStatement
    if (id == R.id.action_leave) {
        leave();
        return true;
    }

    return super.onOptionsItemSelected(item);
}

private void addLog(String message) {
    mMessages.add(new Message.Builder(Message.TYPE_LOG)
            .message(message).build());
    mAdapter.notifyItemInserted(mMessages.size() - 1);
    scrollToBottom();
}

private void addParticipantsLog(int numUsers) {
    addLog(getResources().getQuantityString(R.plurals.message_participants, numUsers, numUsers));
}

private void addMessage(String username, String message) {
    mMessages.add(new Message.Builder(Message.TYPE_MESSAGE)
            .username(username).message(message).build());
    mAdapter.notifyItemInserted(mMessages.size() - 1);
    scrollToBottom();
}

private void addTyping(String username) {
    mMessages.add(new Message.Builder(Message.TYPE_ACTION)
            .username(username).build());
    mAdapter.notifyItemInserted(mMessages.size() - 1);
    scrollToBottom();
}

private void removeTyping(String username) {
    for (int i = mMessages.size() - 1; i >= 0; i--) {
        Message message = mMessages.get(i);
        if (message.getType() == Message.TYPE_ACTION && message.getUsername().equals(username)) {
            mMessages.remove(i);
            mAdapter.notifyItemRemoved(i);
        }
    }
}

private void attemptSend() {
    if (null == mUsername) return;
    if (!mSocket.connected()) return;

    mTyping = false;

    String message = mInputMessageView.getText().toString().trim();
    if (TextUtils.isEmpty(message)) {
        mInputMessageView.requestFocus();
        return;
    }

    mInputMessageView.setText("");
    addMessage(mUsername, message);

    // perform the sending message attempt.
    mSocket.emit("new message", message);
}

private void startSignIn() {
   // mUsername = null;
    Intent intent = new Intent(getActivity(), LoginActivity.class);
    startActivityForResult(intent, REQUEST_LOGIN);
}

private void leave() {
    mUsername = null;
    mSocket.disconnect();
    mSocket.connect();
    startSignIn();
}

private void scrollToBottom() {
    mMessagesView.scrollToPosition(mAdapter.getItemCount() - 1);
}
}

我使用CHAT_SERVER_URL = "http://192.168.1.14:3000/"与服务器建立连接,但它对我不起作用。当我们尝试通过模拟器或计算机系统建立Web连接时,它工作正常。如果我做错了什么,任何人都可以给我一个想法。

感谢。

1 个答案:

答案 0 :(得分:1)

在服务器端调试之后,我知道如何点击我的服务器建立连接,我知道在每种情况下我们都不需要IO.OptionsOptions.query现在它工作得很好。因此,为了更多说明,我在这里发布一个答案:

 //connect to server
public void startRunning() {
    try {
        if (baseUrl != null) {
         socket = IO.socket("http://" + baseUrl + ":3000?uid=" + userId + "&usid=" + userSessionId);
        }
    } catch (URISyntaxException e) {
        e.printStackTrace();
    }
    if (socket == null) return;
    socket
            .on(Socket.EVENT_CONNECT, CONNECTED)
            .on(Socket.EVENT_DISCONNECT, DISCONNECTED)
            .on("chat-message", CHAT_MESSAGE)
            .on("chats-active", CHATS_ACTIVE)
            .on("chat-logout", LOGOUT)
            .on("messages-read", MESSAGE_READ)
            .on("chat-login", CHAT_LOGIN);
    socket.connect();
}