Archived

This forum has been archived. Please start a new discussion on GitHub.

use Glacier2.SessionFactoryHelper can not create session,why?

i use the code like this:

Ice.Communicator ic = null;
Glacier2.SessionHelper _session = null;
Glacier2.SessionPrx session = null;

try
{
Ice.InitializationData initData = new Ice.InitializationData();
initData.properties = Ice.Util.createProperties();
initData.properties.load("C:\\test\\config.sub");
Glacier2.SessionFactoryHelper _factory = new Glacier2.SessionFactoryHelper(initData, this);

string username = "aaa";
string password = "bbb";

_session = _factory.connect(username, password);
ic = _session.communicator();
}
catch
{
MessageBox.Show("Initialization error!");
return;
}

IceStorm.TopicManagerPrx manager;
try
{
manager = IceStorm.TopicManagerPrxHelper.checkedCast(ic.propertyToProxy("TopicManager.Proxy"));
if (manager == null)
{
MessageBox.Show("invalid proxy");
return;
}
}
catch
{
MessageBox.Show("TopicManagerPrx error!");
return;
}


but connected failed.

if I change the code:

try
{
Ice.RouterPrx defaultRouter = ic.getDefaultRouter();
Glacier2.RouterPrx router = Glacier2.RouterPrxHelper.checkedCast(defaultRouter);
string username = "aaa";
string password = "bbb";

try
{
session = router.createSession(username, password);
}
catch (Glacier2.PermissionDeniedException ex)
{
MessageBox.Show("permission denied:" + ex.reason);
}
catch (Glacier2.CannotCreateSessionException ex)
{
MessageBox.Show("cannot create session::" + ex.reason);
}
}
catch
{
MessageBox.Show("Create session error!");
return;
}

IceStorm.TopicManagerPrx manager;
try
{
manager = IceStorm.TopicManagerPrxHelper.checkedCast(ic.propertyToProxy("TopicManager.Proxy"));
if (manager == null)
{
MessageBox.Show("invalid proxy");
return;
}
}
catch
{
MessageBox.Show("TopicManagerPrx error!");
return;
}

it work well, why?

Comments

  • xdm
    xdm La Coruña, Spain
    Hi jianbin

    There are several things wrong in how you use the SessionFactoryHelper, take a look to the Chat Demo articles and code to see how to do that in detail.

    Some comments about the code you posted:

    You need to configure the factory object before you call connect, at least you should call setRouterHost
    _factory.setRouterHost("hostname/ip");
    

    By default the session factory helper will use SSL endpoints only, so you should enable the SSL plugin, not sure if you have enabled that in the configuration file.
    initData.properties.setProperty(
        "Ice.Plugin.IceSSL", "IceSSL:IceSSL.PluginFactory");
    

    if you want to use TCP endpoints instead, you should disable SSL enpoints, calling setSecure
    _factory.setSecure(false);
    

    If your Glacier2 router doesn't listen in the standard port, you also need to configure that port in the factory.
    _factory.setPort(port);
    

    Then your code don't wait for the communicator to be created.
    _session = _factory.connect(username, password);
    ic = _session.communicator();
    

    your cannot access the communicator like that, at that point it has not been initialized yet, your code can only access the communicator only after createdCommunicator method has been called in the callback used to create the session factory.

    Later you create another proxy, that should be done after connected has been called in the callback, connected inform your application that the session has been established successfully.

    I recommend you to review Chat Demo articles specially the second part explain how to use session factory in detail, and the code of the graphical clients will give you even more details.

    If you still have doubts after review, let us know.
  • thanks for help! I have solve my problem.

    but in my .net winform program, i create a thread to process initData.

    in chat demo,


    // Dispatch servant calls and AMI callbacks with this windows Dispatcher.
    initData.dispatcher = delegate(System.Action action, Ice.Connection connection)
    {
    Dispatcher.BeginInvoke(DispatcherPriority.Normal, action);
    };

    can not work in winform, how can i do it in main thread?
  • xdm
    xdm La Coruña, Spain
    but in my .net winform program, i create a thread to process initData.
    I'm not sure what you mean with that.
    can not work in winform, how can i do it in main thread?

    You need the dispatcher, so Ice callbacks are processed from the right thread in that case the GUI main thread.

    See here for examples of windows forms Begin Invoke Control.BeginInvoke Method (Delegate) (System.Windows.Forms)
  • sorry, I use control.begininvoke in my winform program. also cannot work.

    post source in attached file.

    my Glacier2 config file:

    Glacier2.InstanceName=DemoGlacier2

    Glacier2.Client.Endpoints=tcp -p 4063 -h 127.0.0.1

    Glacier2.Server.Endpoints=tcp -h 127.0.0.1

    Glacier2.PermissionsVerifier=DemoGlacier2/NullPermissionsVerifier

    Glacier2.SessionTimeout=30

    Glacier2.Client.Buffered=1
    Glacier2.Server.Buffered=1

    Glacier2.Client.Trace.Request=1
    Glacier2.Server.Trace.Request=1
    Glacier2.Client.Trace.Override=1
    Glacier2.Server.Trace.Override=1
    Glacier2.Client.Trace.Reject=1
    Glacier2.Trace.Session=1
    Glacier2.Trace.RoutingTable=1

    Ice.Warn.Connections=1

    Ice.Trace.Network=2

    subscriber config file:
    Ice.Default.Router=DemoGlacier2/router:tcp -p 4063 -h 127.0.0.1
    Ice.ACM.Client=0
    Ice.RetryIntervals=-1


    Clock.Subscriber.Endpoints=tcp -h 127.0.0.1:udp -h 127.0.0.1

    TopicManager.Proxy=DemoIceStorm/TopicManager:tcp -h 127.0.0.1 -p 10000
  • xdm
    xdm La Coruña, Spain
    You don't say what isn't working, a good description of the problem will help give you better advice.

    Anyway i have take a look to your code:
    initData.properties.load(Application.StartupPath + "\\config.gsub");
    

    When i run the program from the debugger i get an Ice.FileException, because StartupPath is debug/bin but config.gsub is in the root directory.

    I change it to use an absolute path and the connection to glacier2 success

    In your connect implementation you made several synchronous calls, to connect to IceStorm , retrieve the topic manager, that isn't a good idea for a GUI client, but when you use the Ice.Dispatcher is also prone to cause a Deadlock in your code, so i encourage you to use asynchronous calls here or alternatively move the code to a separate Thread.

    string id = null;
    //create Callback
    Ice.ObjectAdapter adapter = ic.createObjectAdapter("Clock.WinSubscriber");
    Ice.Identity subId = new Ice.Identity(id, "Clock.WinSubscriber");
    if (subId.name == null)
    {
        subId.name = Guid.NewGuid().ToString();
    }
    subscriber = adapter.add(new ClockI(this), subId);
    subscriber = subscriber.ice_oneway();
    

    I'm unsure what are your intentions, but most probably you don't want to do that in your client application.

    For that to work the server must need to be able to open a connection to the client, most probably you want to use an object adapter configured with the Glacier2 router used to create the session.

    Look how chat demo create the callback objects. basically you can use _session.addWithUUID(new ClockI(this)) to replace all that code
  • oh, sorry.

    the program is only a ICEStorm clock Subscriber. I want use winform GUI & Glacier2.

    the Server is same as "Ice-3.4.1-demos\democs\IceStorm\clock "
  • ok, I understand. Now Everything is running ok. thank you so much.