自服务以来,我使用一个套接字时收到多个消息

Posted

技术标签:

【中文标题】自服务以来,我使用一个套接字时收到多个消息【英文标题】:Multiple receiving message while I use one socket since a service 【发布时间】:2016-10-28 08:43:49 【问题描述】:

当我发送自服务以来的第一条消息时,我收到一条消息。当我发送第二条消息时,我收到两条消息,等等。我不知道为什么。我想每次发送只收到一条消息。为什么我会得到不止一个?

这是我的代码:

import android.app.IntentService;
import android.app.Service;
import android.content.Context;
import android.content.Intent;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.os.AsyncTask;
import android.os.Binder;
import android.os.Bundle;
import android.os.IBinder;
import android.support.v4.content.LocalBroadcastManager;
import android.util.Base64;
import android.util.Log;
import android.widget.Toast;

import com.github.nkzawa.emitter.Emitter;
import com.github.nkzawa.socketio.client.IO;
import com.github.nkzawa.socketio.client.Socket;

import org.json.JSONException;
import org.json.JSONObject;

import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.net.URISyntaxException;

public class SocketService extends Service 

    final String TAG = "SocketService";
    JSONObject sendMessage;
    private Socket socket;



   private final IBinder mBinder = new MyBinder();
    public class MyBinder extends Binder 

        SocketService getService() 
            return SocketService.this;
        
    

    @Override
    public void onCreate()
         super.onCreate();


        //     Receive receive = new Receive();

      //  receive.execute();
        Connection connection = new Connection();
        connection.execute();

    

    @Override
    public int onStartCommand(Intent intent, int flags, int startId) 

        Receive receive = new Receive();

        receive.execute();

        Bundle extras = intent.getExtras();

        if(extras!= null) 
            String msg = extras.getString("message");
            String encPth = extras.getString("encodeImagePath");

            Send send = new Send();
            send.execute(msg, encPth);
        

        return Service.START_NOT_STICKY;
    


    private String encodeImage(String path)  // Bitmap bm

        File imagefile = new File(path);
        FileInputStream fis = null;
        try 
            fis = new FileInputStream(imagefile);
         catch (FileNotFoundException e) 

            e.printStackTrace();
        

        Bitmap bm = BitmapFactory.decodeStream(fis);
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        bm.compress(Bitmap.CompressFormat.JPEG, 100, baos);
        byte[] b = baos.toByteArray();
        String encImage = Base64.encodeToString(b, Base64.DEFAULT);

        return encImage;
    

    @Override
    public IBinder onBind(Intent intent) 
        // TODO: Return the communication channel to the service.
        throw new UnsupportedOperationException("Not yet implemented");
    

    @Override
    public void onDestroy() 
        super.onDestroy();
        //socket.disconnect();
        Disconnection disconnection = new Disconnection();
        disconnection.execute();
    

    class Connection extends AsyncTask<Void, Void, Void>
        @Override
        protected Void doInBackground(Void... voids) 
            try 
                socket = IO.socket("http://ec2-74-52-49-87.eu-west-1.compute.amazonaws.com");
             catch (URISyntaxException e) 
                throw new RuntimeException(e);
            


            socket.connect();
            return null;
        
    

    class Disconnection extends AsyncTask<Void, Void, Void>
        @Override
        protected Void doInBackground(Void... voids) 

            socket.disconnect();

        return null;
        
    

    class Receive extends AsyncTask<Void, Void, Void>

        @Override
        protected Void doInBackground(Void... voids) 


            Log.d(TAG, "onCreate");
            socket.on(Socket.EVENT_CONNECT, new Emitter.Listener() 

                @Override
                public void call(Object... args) 
                    Log.d(getClass().getCanonicalName(), "Connected to server");
                

            ).on(Socket.EVENT_DISCONNECT, new Emitter.Listener() 

                @Override
                public void call(Object... arg0) 
                    Log.d(getClass().getCanonicalName(), "Disconnected from server");
                

            );
            socket.on("message", new Emitter.Listener() 
                @Override
                public void call(Object... args) 


                            JSONObject data = (JSONObject) args[0];
                            Log.d(TAG, "Handling friendcall");
                            String message = null;
                            String imageText = null;

                            try 
                                if (data.getString("image") != null) 

                                    message = data.getString("text").toString();
                                    imageText = data.getString("image");

                                    Intent in = new Intent();
                                    Bundle extras = new Bundle();
                                    extras.putString("MsgWithImag", message);
                                    extras.putString("Imag", imageText);
                                    in.putExtras(extras);
                                    in.setAction("NOW");

                                    LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(in);
                                    Log.d(TAG, "Call from : " + message + imageText);
                                

                             catch (JSONException e) 
                                //  Log.d(TAG, "friend call object cannot be parsed");
                                e.printStackTrace();
                            

                            try 
                                if (data.getString("sansPhoto") != null) 
                                    message = data.getString("text").toString();

                                    Intent in = new Intent();
                                    in.putExtra("Msg", message);
                                    in.setAction("NOW");

                                    LocalBroadcastManager.getInstance(getApplicationContext()).sendBroadcast(in);

                                
                             catch (JSONException e) 
                                //  Log.d(TAG, "friend call object cannot be parsed");
                                e.printStackTrace();
                            
                        
                    );


            Log.d(TAG, "onStartCommand. Socket should be up");


            return null;
        
    

    class Send extends AsyncTask<Object, Void, Void>

        String msg, encPth, sansPhoto;


        @Override
        protected Void doInBackground(Object... params) 



               msg = (String)params[0];
               encPth = (String)params[1];
                sansPhoto = "g";


                sendMessage = new JSONObject();
                try 

                    if(msg != null) 

                        sendMessage.put("text", msg);

                    

                    if( encPth != null)  //ImageBmp

                        sendMessage.put("image",encodeImage(encPth));
                        //  sendMessage.put("image", encodeImage(ImageBmp));

                    else
                        sendMessage.put("sansPhoto", sansPhoto);
                    


                    socket.emit("message", sendMessage);

                 catch (JSONException e) 
                    e.printStackTrace();
                


            return null;
        
    

【问题讨论】:

第三次发送消息时会发生什么?您收到 3 条消息吗?你需要清除缓冲区吗? 感谢@AdamH 的帮助。他们没有逻辑。在我使用另一部智能手机后,我第一次收到 1 后 1 后 1 后 1 并收到 16 条消息,然后我再次更改并收到 2 条。我不使用缓冲区。 M. @Adam H 请问你有解决方案吗? 【参考方案1】:

我认为您必须在 onCreate 方法中定义 Receive,而不是在 onStartCommand 中。因为每次调用新 Receive 的服务都会启动。

Android onCreate or onStartCommand for starting service

【讨论】:

感谢@mehd azizi 的帮助!我在 onCreate 方法中定义了 Receive 但它不起作用(我有同样的问题)。之后,我添加了 runOnUiThread 但它也不起作用。我总是遇到同样的问题。 ' new Thread(new Runnable() public void run() runOnUiThread(new Runnable() @Override public void run() Receive receive = new Receive(); receive.execute( ); ); )。开始(); ' M. mehd azizi 你有解决办法吗?我一直有这个问题。我没有找到解决方案。请帮忙。

以上是关于自服务以来,我使用一个套接字时收到多个消息的主要内容,如果未能解决你的问题,请参考以下文章

套接字 io 仅在最后接收消息

XMPP 客户端接收服务器消息

同时发送/接收消息套接字python

Android:我在哪里可以在服务中实现 socket.on(...)?我多次收到相同的消息

在 Windows 10 上本地运行 Python 2.7 Web 服务时禁止访问套接字消息

为啥在 useEffect 中侦听套接字事件时对服务器有多个请求?