// <summary>ソースコード：>リモートサービス：通信ユーティリティ</summary>
// <author>CommonMP</author>

using System;

namespace CommonMP.HYSSOP.OptionImpl.HSCommunicationTool.HyssopDotNetIpcTool
{
    /// <summary><para>class outline:</para>
    /// <para>リモートサービス：通信ユーティリティ</para>
    /// </summary>
    /// <remarks><para>history:</para>
    /// <para>[CommonMP][ver 1.0.0][2009/12/28][新規作成]</para>
    /// <para>本クラスは<see cref="MarshalByRefObject"/>の派生クラスで、リモート呼び出しが可能なオブジェクトである。</para>
    /// <para>サーバプロセス側では本クラスを<see cref="HySIpcServiceRegister.CreateServerPort"/>でサーバーオブジェクトとして登録する。</para>
    /// <para>クライアントプロセス側では本クラスを<see cref="HySIpcServiceRegister.CreateClientPort"/>でリモートオブジェクトとして登録する。</para>
    /// <para>以後、クライアントプロセスで<see cref="SendData"/>呼び出しを行うと、常にサーバー側で処理が行われる。</para>
    /// </remarks>
    public class HySIpcRemoteService : MarshalByRefObject
    {
        /// <summary>
        /// オブザーバオブジェクト
        /// </summary>
        protected static HySIpcRemoteSerivceObserverIF m_observer;

        /// <summary><para>method outline:</para>
        /// <para>デフォルトコンストラクタ</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> new HySIpcRemoteService()</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>クライアントプロセスでのインスタンス生成は、実際にはプロキシオブジェクトである。</para>
        /// </remarks>
        public HySIpcRemoteService() { }

        /// <summary><para>method outline:</para>
        /// <para>オブザーバをセットする</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> HySIpcRemoteService.SetObserver(csObserver)</para>
        /// </example>
        /// <param name="csObserver">リモートサービスオブザーバ</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>サーバープロセス側で実際に受信データを処理するオブジェクトを登録する。</para>
        /// </remarks>
        public static void SetObserver(HySIpcRemoteSerivceObserverIF csObserver)
        {
            m_observer = csObserver;
        }

        /// <summary><para>method outline:</para>
        /// <para>オブザーバを取得する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> csObserver = HySIpcRemoteService.GetObserver()</para>
        /// </example>
        /// <param name="">無し</param>
        /// <returns>リモートサービスオブザーバ</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>サーバープロセス側で実際に受信データを処理するオブジェクトを取得する。</para>
        /// </remarks>
        public static HySIpcRemoteSerivceObserverIF GetObserver()
        {
            return m_observer;
        }

        /// <summary><para>method outline:</para>
        /// <para>データを送信する</para>
        /// </summary>
        /// <example><para>usage:</para>
        /// <para> SendData(csName, csData)</para>
        /// </example>
        /// <param name="csName">名前</param>
        /// <param name="csData">データ</param>
        /// <returns>無し</returns>
        /// <exception cref="">無し</exception>
        /// <remarks><para>remarks:</para>
        /// <para>.NET Frameworkに含まれない独自型を送受信する場合、<see cref="System.Runtime.Remoting.Channels.Ipc.IpcChannel"/>内部で型解決エラーが発生する。</para>
        /// <para>そのような場合、データの実体はbyte[]とし、シリアル化およびシリアル化解除は、サーバ・クライアント双方の適切な場所で行うこと。</para>
        /// </remarks>
        public virtual void SendData(string csName, object csData)
        {
            if (m_observer != null)
            {
                m_observer.SendDataNotify(csName, csData);
            }
        }
    }
}
