.net リモーティングに問題があります (そして、これを使用するのは初めての試みなので、これが簡単な解決策を備えたばかげた問題である場合は申し訳ありません)。私の問題の解決策が見つからないので、どこかで答えを逃した場合は事前にお詫び申し上げます。
このコードを使用してサーバー/クライアント システムを構築しています。
サーバ:
public Server() {
DbConnector db = new DbConnector();
BinaryServerFormatterSinkProvider provider = new BinaryServerFormatterSinkProvider();
provider.TypeFilterLevel = TypeFilterLevel.Full;
IDictionary props = new Hashtable();
props["port"] = DbConnector.PORT;
TcpChannel channel = new TcpChannel(props, null, provider);
ChannelServices.RegisterChannel(channel, true);
RemotingConfiguration.RegisterWellKnownServiceType(
typeof(DbConnector), "test",
WellKnownObjectMode.SingleCall);
}
クライアント:
public Form1() {
InitializeComponent();
BinaryServerFormatterSinkProvider provider = new BinaryServerFormatterSinkProvider();
provider.TypeFilterLevel = TypeFilterLevel.Full;
IDictionary props = new Hashtable();
props["port"] = 0;
props["ip"] = DbConnector.IP;
TcpChannel channel = new TcpChannel(props, null, provider);
ChannelServices.RegisterChannel(channel, true);
db = (DbConnector)Activator.GetObject(typeof(DbConnector), "tcp://188.x.x.x/test");
InitRest();
}
ローカルで (localhost と WAN IP の両方で) 試してみると、すべて正常に動作しますが、別のマシンで試してみるとすぐに、クライアントが例外をスローします。
{System.Net.Sockets.SocketException (0x80004005): A connection attempt failed because the connected party did not properly respond after a period of time, or established connection failed because connected host has failed to respond 192.168.0.100:9090
Server stack trace:
ved System.Net.Sockets.Socket.DoConnect(EndPoint endPointSnapshot, SocketAddress socketAddress)
ved System.Net.Sockets.Socket.Connect(EndPoint remoteEP)
ved System.Runtime.Remoting.Channels.RemoteConnection.CreateNewSocket(EndPoint ipEndPoint)
ved System.Runtime.Remoting.Channels.RemoteConnection.CreateNewSocket()
ved System.Runtime.Remoting.Channels.RemoteConnection.GetSocket()
ved System.Runtime.Remoting.Channels.SocketCache.GetSocket(String machinePortAndSid, Boolean openNew)
ved System.Runtime.Remoting.Channels.Tcp.TcpClientTransportSink.SendRequestWithRetry(IMessage msg, ITransportHeaders requestHeaders, Stream requestStream)
ved System.Runtime.Remoting.Channels.Tcp.TcpClientTransportSink.ProcessMessage(IMessage msg, ITransportHeaders requestHeaders, Stream requestStream, ITransportHeaders& responseHeaders, Stream& responseStream)
ved System.Runtime.Remoting.Channels.BinaryClientFormatterSink.SyncProcessMessage(IMessage msg)
Exception rethrown at [0]:
ved ECTunes.Database_Reader.Form1.InitRest() i d:\Dropbox\visual studio 2012\Projects\ECTunes\Database Communicator v0.2\Database Reader\Form1.cs:linje 69
ved ECTunes.Database_Reader.Form1..ctor() i d:\Dropbox\visual studio 2012\Projects\ECTunes\Database Communicator v0.2\Database Reader\Form1.cs:linje 56
ved ECTunes.Database_Reader.Program.Main() i d:\Dropbox\visual studio 2012\Projects\ECTunes\Database Communicator v0.2\Database Reader\Program.cs:linje 16
ved System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
ved System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
ved Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
ved System.Threading.ThreadHelper.ThreadStart_Context(Object state)
ved System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
ved System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
ved System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
ved System.Threading.ThreadHelper.ThreadStart()}
DbConnector のコンストラクターが呼び出されるたびにテキストが出力され、クライアントがサーバーに接続していることがわかりますが、それで立ち往生しています。
もう少しテストした後、問題は接続自体ではなく、生成されたコードであるシステムのエンティティ フレームワーク部分からオブジェクトを返す関数を呼び出すときに発生するようです。示されているように、[Serializable] と :MarshalByRefObject を使用してクラスを既に変更しています。
//------------------------------------------------------------------------------
// <auto-generated>
// This code was generated from a template.
//
// Manual changes to this file may cause unexpected behavior in your application.
// Manual changes to this file will be overwritten if the code is regenerated.
// </auto-generated>
//------------------------------------------------------------------------------
namespace Database
{
using System;
using System.Collections.Generic;
[Serializable]
public partial class customer: MarshalByRefObject
{
public customer()
{
this.car = new HashSet<car>();
}
public int customerId { get; set; }
public string name { get; set; }
public virtual ICollection<car> car { get; set; }
}
}
しかし、クライアント プログラムが「顧客」オブジェクトを返す関数を呼び出し、それにアクセスしようとすると、クライアントは上記の例外をスローします。
私の推測では、クラスが MarshalByRefObject から派生しているため、腹が立つのはコールバック部分です。
クライアントチャネルにも特定のポートを使用しようとしましたが、役に立ちませんでした。
誰かがこれに対する解決策を持っていることを願っています。最終的に重要な部分が欠けているのはおそらく私だけです。