代码之家  ›  专栏  ›  技术社区  ›  xdamir79

android smack java。网连接异常连接被拒绝

  •  0
  • xdamir79  · 技术社区  · 7 年前

    发送给其他客户端的消息。XMPP服务具有粘性属性。 运行3d游戏等繁重应用程序后会出现问题。

    09-20 15:46:06.540 31467-31533/home.chat E/(onCreate):SMACKException: The following addresses failed: '94.x.x.x:5222' failed because java.net.ConnectException: failed to connect to /94.x.x.x (port 5222) after 30000ms: isConnected failed: ECONNREFUSED (Connection refused)
    

    我阅读了这个错误的解释,它意味着: 表示尝试将套接字连接到远程地址和端口时出错的信号。通常,远程拒绝连接(例如,没有进程正在侦听远程地址/端口)。

    在我的xmpp服务中,我有重新连接管理器。它在某些情况下工作正常,但在这种情况下没有任何作用。

    在捕捉到这个异常后,我尝试以编程方式重新启动服务,但这并没有帮助。 有人知道我的代码中是否有错误吗?

    MyService类

    import android.app.Service;
    import android.content.BroadcastReceiver;
    import android.content.Context;
    import android.content.Intent;
    import android.content.IntentFilter;
    import android.net.ConnectivityManager;
    import android.net.NetworkInfo;
    import android.os.Bundle;
    import android.os.IBinder;
    import android.util.Log;
    
    import java.io.File;
    import java.util.Date;
    
    public class MyService extends Service {
    private static String DOMAIN = GlobalVariables.server;
    private static String USERNAME = GlobalVariables.user_id;
    private static String PASSWORD = GlobalVariables.user_password;
    public static MyXMPP xmpp;
    String text = "";
    private LocalDb ldb;
    private Boolean disconnectAppeared = false;
    BroadcastReceiver br = null;
    Date d1 = null;
    Date d2 = null;
    static MyService instance;
    
    public static MyService getInstance(){
        return instance;
    }
    
    @Override
    public IBinder onBind(final Intent intent) {
        return new LocalBinder<MyService>(this);
    }
    
    @Override
    public void onCreate() {
        super.onCreate();
        instance = this;
        checkInternetConnection();
        xmpp = MyXMPP.getInstance(MyService.this, DOMAIN, USERNAME, PASSWORD);
        connect();
    
        Log.e("MyService"," created");
    }
    
    public static void connect(){
        xmpp.connect("onCreate");
    }
    
    @Override
    public int onStartCommand(final Intent intent, final int flags,
                              final int startId) {
        return Service.START_STICKY;
    }
    
    @Override
    public boolean onUnbind(final Intent intent) {
        return super.onUnbind(intent);
    }
    
    @Override
    public void onDestroy() {
        super.onDestroy();
        Log.e("MyService"," destroyed");
        xmpp.disconnect();
        unregisterReceiver(br);
        Log.i("EXIT", "ondestroy!");
        Intent broadcastIntent = new Intent("home.chat.ActivityRecognition.RestartService");
        sendBroadcast(broadcastIntent);
    }
    
    private void checkInternetConnection() {
        if (br == null) {
            br = new BroadcastReceiver() {
                @Override
                public void onReceive(Context context, Intent intent) {
                    Bundle extras = intent.getExtras();
                    NetworkInfo info = (NetworkInfo) extras
                            .getParcelable("networkInfo");
                    NetworkInfo.State state = info.getState();
                    Log.d("TEST Internet", info.toString() + " "
                            + state.toString());
                    if (state == NetworkInfo.State.CONNECTED & disconnectAppeared) { //on
                            xmpp.connect("After network changes");
                        disconnectAppeared = false;
                    }
                    if (state == NetworkInfo.State.DISCONNECTED) { //off
                        disconnectAppeared = true;
                    }
                }
            };
            final IntentFilter intentFilter = new IntentFilter();
            intentFilter.addAction(ConnectivityManager.CONNECTIVITY_ACTION);
            registerReceiver(br, intentFilter);
        }
    }
    public void destroyService(){
        stopSelf();
    }
    }
    

    package home.chat;
    
    import *;
    
    public class MyXMPP {
    
    public static boolean connected = false;
    public static boolean loggedin = false;
    public static boolean isconnecting = false;
    public static boolean isToasted = false;
    private boolean chat_created = false;
    private String serverAddress;
    public static XMPPTCPConnection connection;
    public static String loginUser;
    public static String passwordUser;
    Gson gson;
    static MyService context;
    public static MyXMPP instance = null;
    public static boolean instanceCreated = false;
    private Handler mHandler = new Handler();
    public static ReconnectionManager connMgr;
    int[] rt_arr = {2,2,2,5,5,10,10};
    int curr_delay = 0;
    public static ConnectivityManager cm = null;
    public NetworkInfo activeNetwork = null;
    public static Roster myRoster;
    
    static ArrayList<ChatMessage> msg_array = new ArrayList<ChatMessage>(); //буфер сообщений для отправки
    public static ArrayList<HashMap<String,String>> msg_queue = new ArrayList<>();
    public static ArrayList<HashMap<String,String>> stat_list = new ArrayList<>();
    public String senderName = "";
    
    public MyXMPP(MyService context, String serverAdress, String logiUser,
                  String passwordser) {
        this.serverAddress = serverAdress;
        this.loginUser = logiUser;
        this.passwordUser = passwordser;
        this.context = context;
        init();
    }
    
    public static MyXMPP getInstance(MyService context, String server,
                                     String user, String pass) {
        if (instance == null) {
            instance = new MyXMPP(context, server, user, pass);
            instanceCreated = true;
            Log.e("MyXMPP","create new instance");
        }
        return instance;
    }
    
    public org.jivesoftware.smack.chat.Chat Mychat;
    
    ChatManagerListenerImpl mChatManagerListener;
    MMessageListener mMessageListener;
    
    String text = "";
    String mMessage = "", mReceiver = "";
    
    static {
        try {
            Class.forName("org.jivesoftware.smack.ReconnectionManager");
        } catch (ClassNotFoundException ex) {
            Log.e("E:","problem loading reconnection manager");
            // problem loading reconnection manager
        }
    }
    
    public void init() {
        gson = new Gson();
        mMessageListener = new MMessageListener();
        mChatManagerListener = new ChatManagerListenerImpl();
        initialiseConnection();
    }
    
    private void initialiseConnection() {
    
        cm =
                (ConnectivityManager)context.getSystemService(Context.CONNECTIVITY_SERVICE);
        activeNetwork = cm.getActiveNetworkInfo();
    
        XMPPTCPConnectionConfiguration.Builder config = XMPPTCPConnectionConfiguration
                .builder();
        config.setSendPresence(true);
        config.setSecurityMode(XMPPTCPConnectionConfiguration.SecurityMode.required);
        config.setCompressionEnabled(true);
        config.setServiceName(GlobalVariables.service);
        config.setHost(serverAddress);
        config.setPort(5222);
        config.setDebuggerEnabled(true);
    
        try {
            SSLContext sc = SSLContext.getInstance("TLS");
            MemorizingTrustManager mtm = new MemorizingTrustManager(context);
            sc.init(null, new X509TrustManager[] { mtm }, new java.security.SecureRandom());
            config.setCustomSSLContext(sc);
            config.setHostnameVerifier(mtm.wrapHostnameVerifier(new org.apache.http.conn.ssl.StrictHostnameVerifier()));
        } catch (NoSuchAlgorithmException e) {
            throw new IllegalStateException(e);
        } catch (KeyManagementException e) {
            throw new IllegalStateException(e);
        }
        connection = new XMPPTCPConnection(config.build());
        XMPPConnectionListener connectionListener = new XMPPConnectionListener();
        connection.addConnectionListener(connectionListener);
    
        PingManager pingManager = PingManager.getInstanceFor(connection);
        pingManager.setPingInterval(900); // 15 min
        pingManager.registerPingFailedListener(new PingFailedListener(){
            @Override
            public void pingFailed() {
                // Do operation to handle if ping fail like force reconnect etc
                Log.e("PingManager","Ping Failed, reconnection");
                connected = false;
                chat_created = false;
                loggedin = false;
                //disconnect();
                connect("ping_manager");
            }
    
        });
        ServerPingWithAlarmManager.getInstanceFor(connection).isEnabled(); //для пинга во время глубокого сна
    }
    
    public void disconnect() {
        new Thread(new Runnable() {
            @Override
            public void run() {
                connection.disconnect();
            }
        }).start();
    }
    
    public void connect(final String caller) {
        AsyncTask<Void, Void, Boolean> connectionThread = new AsyncTask<Void, Void, Boolean>() {
            @Override
            protected synchronized Boolean doInBackground (Void...arg0){
                if (connection.isConnected())
                    return false;
                isconnecting = true;
                if (isToasted)
                    new Handler(Looper.getMainLooper()).post(new Runnable() {
    
                        @Override
                        public void run() {
    
                            Toast.makeText(context, caller + "=>connecting....", Toast.LENGTH_LONG).show();
                        }
                    });
                Log.e("Connect() Function", caller + "=&gt;connecting....");
    
                try {
                    connection.setPacketReplyTimeout(20000);
                    // Enable automatic reconnection
                    connMgr = ReconnectionManager.getInstanceFor(connection);
                    connMgr.enableAutomaticReconnection();
                    connMgr.setFixedDelay(2);
                    //connMgr.setDefaultFixedDelay(1);
                    //connMgr.setReconnectionPolicy(ReconnectionManager.ReconnectionPolicy.FIXED_DELAY);
                    connection.connect();
                    DeliveryReceiptManager dm = DeliveryReceiptManager
                            .getInstanceFor(connection);
                    dm.setAutoReceiptMode(AutoReceiptMode.always);
                    dm.addReceiptReceivedListener(new ReceiptReceivedListener() {
    
                        @Override
                        public void onReceiptReceived(final String fromid,
                                                      final String toid, final String msgid,
                                                      final Stanza packet) {
    
                        }
                    });
                    connected = true;
                    MainActivity.fConn = true;
                } catch (IOException e) {
                    if (isToasted)
                        new Handler(Looper.getMainLooper())
                                .post(new Runnable() {
    
                                    @Override
                                    public void run() {
    
                                        Toast.makeText(
                                                context,
                                                "(" + caller + ")"
                                                        + "IOException: ",
                                                Toast.LENGTH_SHORT).show();
                                    }
                                });
    
                    Log.e("(" + caller + ")", "IOException: " + e.getMessage());
                } catch (SmackException e) {
                    new Handler(Looper.getMainLooper()).post(new Runnable() {
                        @Override
                        public void run() {
                          // Toast.makeText(context, "(" + caller + ")" + "SMACKException: ", Toast.LENGTH_SHORT).show();
                        }
                    });
                    Log.e("(" + caller + ")",
                            "SMACKException: " + e.getMessage());
                    //mHandler.post(checkConn); //!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!<-- Problem place
                    //instance = null;
                    //MyService.getInstance().destroyService(); 
                } catch (XMPPException e) {
                    if (isToasted)
    
                        new Handler(Looper.getMainLooper())
                                .post(new Runnable() {
    
                                    @Override
                                    public void run() {
    
                                        Toast.makeText(
                                                context,
                                                "(" + caller + ")"
                                                        + "XMPPException: ",
                                                Toast.LENGTH_SHORT).show();
                                    }
                                });
                    Log.e("connect(" + caller + ")",
                            "XMPPException: " + e.getMessage());
    
                }
                return isconnecting = false;
            }
        } ;
        connectionThread.execute();
    }
    
    public static void login() {
        try {
            Log.e(loginUser,passwordUser);
            loginUser = GlobalVariables.user_id;
            passwordUser = GlobalVariables.user_password;
            connection.login(loginUser, passwordUser);
            Log.e("LOGIN", "Yey! We're connected to the Xmpp server!");
            sendBufMessages();
            myRoster = Roster.getInstanceFor(connection);
            if (!myRoster.isLoaded()) {
                try{ myRoster.reloadAndWait(); }
                catch (Exception e) {System.out.println(e);}
            }
            myRoster.setDefaultSubscriptionMode(Roster.SubscriptionMode.accept_all);
            myRoster.addRosterListener(new RosterListener() {
                public void entriesAdded(Collection<String> addresses) {}
                public void entriesDeleted(Collection<String> addresses) {}
                public void entriesUpdated(Collection<String> addresses) {}
                public void presenceChanged(Presence presence) {
                    Log.e("Roster","Presence changed: " + presence.getFrom() + " " + presence);
                    String uname = presence.getFrom();
                    int pos = uname.indexOf('@',0);
                    uname = uname.substring(0,pos);
                    Presence.Type ptype = presence.getType(); //Presence.type.available
                    for(int i=0;i<stat_list.size();i++){
                        HashMap<String,String> item = new HashMap<String, String>();
                        item = stat_list.get(i);
                        if (uname.equals(item.get("user_id").toString())) { stat_list.remove(i); break;}
                    }
                    HashMap<String,String> item = new HashMap<>();
                    item.put("user_id",uname);
                    if (ptype == Presence.Type.available){ item.put("onl","true"); }
                    if (ptype == Presence.Type.unavailable){ item.put("onl","false"); }
                    stat_list.add(0,item);
                    if (MainActivity.chatlist_selected) { ChatList.getInstance().startStatProc(); }
                    if (GlobalVariables.onchat == true & GlobalVariables.vuser_id.equals(uname)){
                        if (ptype == Presence.Type.available) { Chat.setUserStatus("onl"); }
                        if (ptype == Presence.Type.unavailable) {Chat.setUserStatus("offl");}
                    }
                }
            });
        } catch (XMPPException | SmackException | IOException e) {
            e.printStackTrace();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    
    private class ChatManagerListenerImpl implements ChatManagerListener {
        @Override
        public void chatCreated(final org.jivesoftware.smack.chat.Chat chat,
                                final boolean createdLocally) {
            if (!createdLocally)
                chat.addMessageListener(mMessageListener);
    
        }
    
    }
    
    public void sendMessage(ChatMessage chatMessage) {
    .....
    }
    
    public class XMPPConnectionListener implements ConnectionListener {
        @Override
        public void connected(final XMPPConnection connection) {
    
            Log.e("xmpp", "Connected!");
            connected = true;
            curr_delay = 0; connMgr.setFixedDelay(2);
                login();
        }
    
        @Override
        public void connectionClosed() {
            if (isToasted)
    
                new Handler(Looper.getMainLooper()).post(new Runnable() {
    
                    @Override
                    public void run() {
                        // TODO Auto-generated method stub
    
                        Toast.makeText(context, "ConnectionCLosed!",
                                Toast.LENGTH_SHORT).show();
    
                    }
                });
            Log.d("xmpp", "ConnectionCLosed!");
            connected = false;
            chat_created = false;
            loggedin = false;
        }
    
        @Override
        public void connectionClosedOnError(Exception arg0) {
            if (isToasted)
                new Handler(Looper.getMainLooper()).post(new Runnable() {
    
                    @Override
                    public void run() {
                        Toast.makeText(context, "ConnectionClosedOn Error!!",
                                Toast.LENGTH_SHORT).show();
    
                    }
                });
            Log.e("xmpp", "ConnectionClosedOn Error!");
            connected = false;
            chat_created = false;
            loggedin = false;
        }
    
        @Override
        public void reconnectingIn(int arg0) {
    
            Log.e("xmpp", "Reconnectingin " + arg0);
            if (arg0==0 & curr_delay<5){
                curr_delay++;
                connMgr.setFixedDelay(rt_arr[curr_delay]);
            }
            loggedin = false;
        }
    
        @Override
        public void reconnectionFailed(Exception arg0) {
            if (isToasted)
    
                new Handler(Looper.getMainLooper()).post(new Runnable() {
    
                    @Override
                    public void run() {
    
                        Toast.makeText(context, "ReconnectionFailed!",
                                Toast.LENGTH_SHORT).show();
    
                    }
                });
            Log.d("xmpp", "ReconnectionFailed!");
            connected = false;
    
            chat_created = false;
            loggedin = false;
        }
    
        @Override
        public void reconnectionSuccessful() {
            if (isToasted)
    
                new Handler(Looper.getMainLooper()).post(new Runnable() {
    
                    @Override
                    public void run() {
                        // TODO Auto-generated method stub
    
                        Toast.makeText(context, "REConnected!",
                                Toast.LENGTH_SHORT).show();
    
                    }
                });
            Log.d("xmpp", "ReconnectionSuccessful");
            curr_delay = 0; connMgr.setFixedDelay(2);
            connected = true;
            //MainActivity.fConn = true;
            chat_created = false;
            loggedin = false;
        }
    
        @Override
        public void authenticated(XMPPConnection arg0, boolean arg1) {
            Log.d("xmpp", "Authenticated!");
            loggedin = true;
    
            ChatManager.getInstanceFor(connection).addChatListener(
                    mChatManagerListener);
    
            chat_created = false;
            new Thread(new Runnable() {
    
                @Override
                public void run() {
                    try {
                        sleep(500);
                    } catch (InterruptedException e) {
                        // TODO Auto-generated catch block
                        e.printStackTrace();
                    }
    
                }
            }).start();
            if (isToasted)
    
                new Handler(Looper.getMainLooper()).post(new Runnable() {
    
                    @Override
                    public void run() {
                        // TODO Auto-generated method stub
    
                        Toast.makeText(context, "Connected!",Toast.LENGTH_SHORT).show();
    
                    }
                });
        }
    }
    
    private class MMessageListener implements ChatMessageListener {
    
        @Override
        public void processMessage(final org.jivesoftware.smack.chat.Chat chat,
                                   final Message message) {
            Log.i("MyXMPP_MESSAGE_LISTENER", "Xmpp message received: '"
                    + message);
    
    ...
            }
        }
    
    
    
    private Runnable checkConn = new Runnable() {
        public void run() {
            try {
                Socket socket = new Socket(host, 5222);
                socket.shutdownInput();
                socket.shutdownOutput();
                socket.close();
            } catch(Exception e){Log.e("Socket",e.toString());}
            disconnect();
            Log.e("MyXMPP","disconnect");
            mHandler.postDelayed(checkConn2,3000);
        }
    };
    private Runnable checkConn2 = new Runnable() {
        public void run() {
            connect("After SmackException");
        }
    };
    
    
    }
    

    更新26.09.17。经过几天的实验,我仍然没有找到解决办法。 我尝试使用前台服务、PingManager和broadcastreceiver来重新创建服务,但没有结果。现在我尝试在系统内存不足时使用压力信号。 更新05.10.17我仍然没有找到解决方案。我在Android 4.1.2上测试了这个程序。它工作得很好。在Android 5.1.1上,它在退出活动后大约3分钟工作,然后我收到连接被拒绝错误。当我返回活动时,错误消失了。Android 6.0.1上的情况类似,但错误与java略有不同。网SocketTimeoutException:10000ms后无法连接到/94.130.25.242(端口80)。我认为系统会在一段时间后阻止服务中的网络活动,但不会阻止活动(?)。

    2 回复  |  直到 7 年前
        1
  •  0
  •   xdamir79    7 年前

    小米手机不可能在后台使用长网络连接。MIUI会在一段时间后阻止任何网络连接。对于关键网络连接,您可以使用Firebase云消息传递,这在Android系统中具有高优先级。它可以启动必要的后台工作。

        2
  •  0
  •   iGroza UnboxedSoul    4 年前

    尝试在中添加权限 AndroidManifest.xml

        <uses-permission android:name="android.permission.INTERNET"/>
        <uses-permission android:name="android.permission.ACCESS_NETWORK_STATE"/>
        <uses-permission android:name="android.permission.WAKE_LOCK"/>
        <uses-permission android:name="android.permission.FOREGROUND_SERVICE"/>
        <uses-permission android:name="android.permission.REQUEST_COMPANION_RUN_IN_BACKGROUND"/>
        <uses-permission android:name="android.permission.REQUEST_IGNORE_BATTERY_OPTIMIZATIONS"/>
        <uses-permission android:name="android.permission.REQUEST_COMPANION_USE_DATA_IN_BACKGROUND"/>
    

    和下面的代码 onCreate() 为您服务。我希望它能帮助别人。

    PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE);
                if (pm != null) {
                    if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
                        Intent intent = new Intent();
                        String packageName = getPackageName();
                        if (!pm.isIgnoringBatteryOptimizations(packageName)) {
                            intent.setAction(Settings.ACTION_REQUEST_IGNORE_BATTERY_OPTIMIZATIONS);
                            intent.setData(Uri.parse("package:" + packageName));
                            startActivity(intent);
                        }
                    }
    
                    Log.d(TAG, "PowerManager.SCREEN_DIM_WAKE_LOCK+PowerManager.ON_AFTER_RELEASE");
                    pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK + PowerManager.ON_AFTER_RELEASE, "wetwars:activityrecognition").acquire();
                    pm.newWakeLock(PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP | PowerManager.ON_AFTER_RELEASE, "WetWars:WakeLockActivity").acquire();
                }