.net 원격, 델리게이트가 잘못된 프로세스에서 호출 됨

J. Doe

.net 원격으로 몇 가지 테스트를 수행하고 있으며 위임을 사용하는 동안 문제가 있음을 발견했습니다.

서버 및 클라이언트 자체 인 단일 앱이 있습니다. 사용자가 탐색기에서 앱을 처음 실행하면 서버로 실행되고 클라이언트로 새 프로세스를 시작합니다. 둘 다 잘 작동합니다. 이제 사용자가 서버와 클라이언트 프로세스가 여전히 실행 중일 때 다시 실행하면 클라이언트가되어 새로운 프로세스가 시작되었다는 메시지를 서버에 보낸 다음 자체적으로 종료된다고 가정합니다.

대리인이 클라이언트 대신 서버 프로세스에서 실행되는 것을 제외하고는 모두 잘 작동합니다.

다음은 코드입니다.

    const string PIPE_NAME = "testPipeName33";
    const string OBJECT_NAME = "test";
    static RemoteObject remoteObject;
    static void RegisterClient()
    {
        IpcClientChannel chan = new IpcClientChannel();
        ChannelServices.RegisterChannel(chan, false);

        remoteObject = (RemoteObject)Activator.GetObject(typeof(RemoteObject),
                string.Format("ipc://{0}/{1}", PIPE_NAME, OBJECT_NAME));
    }
    static void RegisterServer()
    {
        BinaryServerFormatterSinkProvider serverProvider = new BinaryServerFormatterSinkProvider();
        serverProvider.TypeFilterLevel = TypeFilterLevel.Full;

        IpcServerChannel chan = new IpcServerChannel("", PIPE_NAME, serverProvider);
        ChannelServices.RegisterChannel(chan, false);

        RemotingServices.Marshal(new RemoteObject(), OBJECT_NAME);
    }

    [STAThread]
    static void Main(string[] args)
    {
        Application.EnableVisualStyles();
        Application.SetCompatibleTextRenderingDefault(false);
        if ((args.Length == 0 || args[0] == "s"))
        {
            try
            {
                RegisterServer();
            }
            catch (RemotingException)
            {
                // try to register it with the pipe name. If it fails, means server is already running.
                //bad idea, I know, but it's just for barebone quick test
                RegisterClient();
                remoteObject.OnNewProcessStarted("test");
                Application.Exit();
                return;
            }

            Process.Start(Application.ExecutablePath, "c");
            Application.Run(new Form1("Server"));

        }
        else
        {
            IsClient = true;
            RegisterClient();
            remoteObject.SetOnNewProcessStarted(OnNewProcessStarted);

            Application.Run(new Form1("Client"));

        }
    }


    static bool IsClient = false;
    static bool OnNewProcessStarted(string commandLine)
    {
        MessageBox.Show("Is Client : " + IsClient);//problem here, IsClient should be true
        return true;
    }

RemoteObject 클래스.

public delegate bool OnNewProcessStartedDelegate(string text);

internal class RemoteObject : MarshalByRefObject
{
    public OnNewProcessStartedDelegate OnNewProcessStartedHandler;
    public bool OnNewProcessStarted(string commandLine)
    {
        if (OnNewProcessStartedHandler != null)
            return OnNewProcessStartedHandler(commandLine);
        return false;
    }

    public void SetOnNewProcessStarted(OnNewProcessStartedDelegate onNewProcessStarted)
    {
        OnNewProcessStartedHandler = onNewProcessStarted;
    }

    public override object InitializeLifetimeService()
    {
        return null;
    }
}

추신 : 하나의 서버와 하나의 클라이언트 만있을 수 있습니다.

비루

새 클라이언트가 서버에서 RemoteObject의 델리게이트를 호출하기 때문에 Delegate가 서버에서 실행 중입니다. 서버와 첫 번째 클라이언트 사이에 등록 된 콜백이 없습니다. 요청을 수신하는 첫 번째 클라이언트에 아무도 없기 때문에 서버는 콜백 할 프로세스를 알지 못합니다. 일반적으로 WCF와 같은 기술을 사용하면 이중 통신을 허용하는 DualHttpBindings를 사용할 수 있지만 여기서는 CallBack이 없습니다. 그래서 우리는 첫 번째 클라이언트 프로세스에서 델리게이트가 호출되는지 확인하기 위해 첫 번째 클라이언트에서 RemoteObject로 콜백 채널을 등록해야합니다. 디버깅 목적으로 프로세스 ID를 추가했습니다.

  static class Program
    {
        /// <summary>
        /// The main entry point for the application.
        /// </summary>
        [STAThread]
        static void Main(string[] args)
        {
            const string PIPE_NAME = "testPipeName33";
            const string OBJECT_NAME = "test";
            const string CALLBACK_PIPE_NAME = "testPipeName34";
            const string CALLBACK_OBJECT_NAME = "testclient";

            Application.EnableVisualStyles();
            Application.SetCompatibleTextRenderingDefault(false);
            if ((args.Length == 0 || args[0] == "s"))
            {
                try
                {
                   IPCRegistration.RegisterServer(PIPE_NAME,OBJECT_NAME);
                }
                catch (RemotingException)
                {
                                        remoteObject = IPCRegistration.RegisterClient(typeof(RemoteObject),PIPE_NAME,OBJECT_NAME);
                    remoteObject.OnNewProcessStarted("test");
                    Application.Exit();
                    return;
                }
                MessageBox.Show("Server:" + Process.GetCurrentProcess().Id);
                Process.Start(Application.ExecutablePath, "c");
                Application.Run(new Form1("Server"));

            }
            else
            {
                IsClient = true;
                remoteObject = IPCRegistration.RegisterClient(typeof(RemoteObject), PIPE_NAME, OBJECT_NAME);
                IPCRegistration.RegisterServer(CALLBACK_PIPE_NAME, CALLBACK_OBJECT_NAME); // Here Client will listen on this channel.
                remoteObject.SetOnNewProcessStarted(OnNewProcessStarted,Process.GetCurrentProcess().Id.ToString());
                MessageBox.Show("Client:" + Process.GetCurrentProcess().Id);
                Application.Run(new Form1("Client"));

            }
        }


        static RemoteObject remoteObject;

        static bool IsClient = false;
        static bool OnNewProcessStarted(string commandLine)
        {
            MessageBox.Show("saved:"+commandLine+" Currrent:"+Process.GetCurrentProcess().Id);
            MessageBox.Show("Is Client : " + IsClient);//problem here, IsClient should be true
            return true;
        }
    }

    public delegate bool OnNewProcessStartedDelegate(string text);

    internal class RemoteObject : MarshalByRefObject
    {
        public OnNewProcessStartedDelegate OnNewProcessStartedHandler;
        public string value;
        public bool isCallBack = false;
        const string PIPE_NAME = "testPipeName33";
        const string OBJECT_NAME = "test";
        const string CALLBACK_PIPE_NAME = "testPipeName34";
        const string CALLBACK_OBJECT_NAME = "testclient";
        RemoteObject remoteObject;
        public bool OnNewProcessStarted(string commandLine)
        {
            if (!isCallBack)
            {
                remoteObject.isCallBack = true;
                return remoteObject.OnNewProcessStarted(commandLine);
            }

            if (OnNewProcessStartedHandler != null)
                return OnNewProcessStartedHandler(value);
            return false;
        }



        public void SetOnNewProcessStarted(OnNewProcessStartedDelegate onNewProcessStarted,string value)
        {
            this.value = value;
            OnNewProcessStartedHandler = onNewProcessStarted;
            if (!isCallBack)
            {
                remoteObject = IPCRegistration.RegisterClient(typeof(RemoteObject), CALLBACK_PIPE_NAME, CALLBACK_OBJECT_NAME);
                remoteObject.isCallBack = true;
                remoteObject.SetOnNewProcessStarted(onNewProcessStarted, Process.GetCurrentProcess().Id.ToString());
            }
        }

        public override object InitializeLifetimeService()
        {
            return null;
        }
    }

    internal class IPCRegistration
    {
       public  static RemoteObject RegisterClient(Type remoteObject,string PIPE_NAME,string OBJECT_NAME)
        {
            IpcClientChannel chan = new IpcClientChannel();
            ChannelServices.RegisterChannel(chan, false);

            RemoteObject remoteObjectInstance = (RemoteObject)Activator.GetObject(remoteObject,
                    string.Format("ipc://{0}/{1}", PIPE_NAME, OBJECT_NAME));
            return remoteObjectInstance;
        }
        public static void RegisterServer(string pipeName, string objectName)
        {
            BinaryServerFormatterSinkProvider serverProvider = new BinaryServerFormatterSinkProvider();
            serverProvider.TypeFilterLevel = TypeFilterLevel.Full;

            IpcServerChannel chan = new IpcServerChannel("", pipeName, serverProvider);
            ChannelServices.RegisterChannel(chan, false);

            RemotingServices.Marshal(new RemoteObject(), objectName);
        }
    }

이 기사는 인터넷에서 수집됩니다. 재 인쇄 할 때 출처를 알려주십시오.

침해가 발생한 경우 연락 주시기 바랍니다[email protected] 삭제

에서 수정
0

몇 마디 만하겠습니다

0리뷰
로그인참여 후 검토

관련 기사

분류에서Dev

Javascript WebRTC 원격 응답 설정 실패 sdp : 잘못된 상태로 호출 됨 : kHaveRemoteOffer 및 잘못된 상태로 호출 됨 : kStable

분류에서Dev

어셈블리 호출이 잘못된 주소로 매핑 됨

분류에서Dev

OS X 명령 줄에서 잘못된 ctag가 호출 됨

분류에서Dev

UITableViewCell에서 호출 된 UIActivityViewController가 잘못 표시됨

분류에서Dev

생성자가 잘못된 시간에 호출 됨

분류에서Dev

잘못된 BindingHandler가 호출 됨

분류에서Dev

두 번째 생성자가 C ++에서 호출 됨 (잘못된 출력)

분류에서Dev

Angular 10 및 RxJ에서 잘못된 동작 유형 또는 잘못된 감속기가 호출 됨

분류에서Dev

세션 설명 설정 실패 : OperationError : 원격 응답 설정 실패 sdp : 잘못된 상태로 호출 됨 : STATE_INPROGRESS

분류에서Dev

gRPC 단항 호출에서 'start_batch가 잘못 호출 됨'

분류에서Dev

WebAPI 2 : 기본 GET ALL이 잘못된 매개 변수로 호출 됨

분류에서Dev

서명 차이로 인해 잘못된 자식 클래스 함수가 호출 됨

분류에서Dev

반환 된 간격에 관계없이 reportPlaySeconds가 호출 됨

분류에서Dev

잘못된 컨트롤러 함수가 호출 됨

분류에서Dev

JRMI 클라이언트로 .NET 원격 기능 호출

분류에서Dev

현재 스크롤 위치가 잘못된 번호로 업데이트 됨

분류에서Dev

여러 공유 라이브러리에서 호출되고 libstdc ++ 정적 링크가 활성화 된 경우 C ++ 스트림이 잘못됨

분류에서Dev

NodeJS의 원격 호스트에서 프로세스 생성

분류에서Dev

FFMPEG : 이미지가 잘못된 FPS에서 잘못로드 됨

분류에서Dev

c ++-잘못된 소멸자가 호출 됨

분류에서Dev

잘못된 템플릿 함수가 호출 됨

분류에서Dev

VS Team Services에서 연속 통합시 '이 버전 제어 호스트는 지원되지 않습니다'라는 잘못된 오류가 표시됨

분류에서Dev

onCreate () 및 onPause ()가 다른 활동에서 잘못 호출 됨

분류에서Dev

Docusign 업로드 API 호출이 원격 서버에서 오류를 반환했습니다. (400) 잘못된 요청

분류에서Dev

for 루프의 tar 명령이 잘못된 번호에서 시작됨

분류에서Dev

Postman에서 Rest API를 호출 할 수 있으며 Java에서 400 개의 잘못된 요청이 표시됨

분류에서Dev

잘못된 길이로 sendto () 호출

분류에서Dev

지원 라이브러리 업데이트 후 ViewPager에 잘못된 페이지가 표시됨

분류에서Dev

단일 URL 호출에서 형식이 잘못된 CSV (3 개의 csv 연결됨) 읽기

Related 관련 기사

  1. 1

    Javascript WebRTC 원격 응답 설정 실패 sdp : 잘못된 상태로 호출 됨 : kHaveRemoteOffer 및 잘못된 상태로 호출 됨 : kStable

  2. 2

    어셈블리 호출이 잘못된 주소로 매핑 됨

  3. 3

    OS X 명령 줄에서 잘못된 ctag가 호출 됨

  4. 4

    UITableViewCell에서 호출 된 UIActivityViewController가 잘못 표시됨

  5. 5

    생성자가 잘못된 시간에 호출 됨

  6. 6

    잘못된 BindingHandler가 호출 됨

  7. 7

    두 번째 생성자가 C ++에서 호출 됨 (잘못된 출력)

  8. 8

    Angular 10 및 RxJ에서 잘못된 동작 유형 또는 잘못된 감속기가 호출 됨

  9. 9

    세션 설명 설정 실패 : OperationError : 원격 응답 설정 실패 sdp : 잘못된 상태로 호출 됨 : STATE_INPROGRESS

  10. 10

    gRPC 단항 호출에서 'start_batch가 잘못 호출 됨'

  11. 11

    WebAPI 2 : 기본 GET ALL이 잘못된 매개 변수로 호출 됨

  12. 12

    서명 차이로 인해 잘못된 자식 클래스 함수가 호출 됨

  13. 13

    반환 된 간격에 관계없이 reportPlaySeconds가 호출 됨

  14. 14

    잘못된 컨트롤러 함수가 호출 됨

  15. 15

    JRMI 클라이언트로 .NET 원격 기능 호출

  16. 16

    현재 스크롤 위치가 잘못된 번호로 업데이트 됨

  17. 17

    여러 공유 라이브러리에서 호출되고 libstdc ++ 정적 링크가 활성화 된 경우 C ++ 스트림이 잘못됨

  18. 18

    NodeJS의 원격 호스트에서 프로세스 생성

  19. 19

    FFMPEG : 이미지가 잘못된 FPS에서 잘못로드 됨

  20. 20

    c ++-잘못된 소멸자가 호출 됨

  21. 21

    잘못된 템플릿 함수가 호출 됨

  22. 22

    VS Team Services에서 연속 통합시 '이 버전 제어 호스트는 지원되지 않습니다'라는 잘못된 오류가 표시됨

  23. 23

    onCreate () 및 onPause ()가 다른 활동에서 잘못 호출 됨

  24. 24

    Docusign 업로드 API 호출이 원격 서버에서 오류를 반환했습니다. (400) 잘못된 요청

  25. 25

    for 루프의 tar 명령이 잘못된 번호에서 시작됨

  26. 26

    Postman에서 Rest API를 호출 할 수 있으며 Java에서 400 개의 잘못된 요청이 표시됨

  27. 27

    잘못된 길이로 sendto () 호출

  28. 28

    지원 라이브러리 업데이트 후 ViewPager에 잘못된 페이지가 표시됨

  29. 29

    단일 URL 호출에서 형식이 잘못된 CSV (3 개의 csv 연결됨) 읽기

뜨겁다태그

보관