Ice topic: Implementing chat rooms through ice

Source: Internet
Author: User

For network applications, the simple model is to send requests and wait for responses. I call this model a ticket model. The server cannot actively notify the client of what happened, only passively wait for the client to request and respond, the most classic is the HTTP service. This is enough for this model, but this is not enough for the interaction between the server and the customer, requires a duplex model, that is, mutual notification between the server and the customer. For this model, the most obvious problem is a chat room where many people chat. What a person says has to go through the server and inform others, this requires a simple interaction between the server and the client, but it is enough to illustrate the problem. The appearance of ice makes this model simple. Next I will introduce how to use ice to develop chat rooms.

As described above, all we have to do is broadcast the information sent from a client to other clients, which is such a simple operation. To achieve this purpose, you must open a listening port on both the server side and the client side to interact with each other. At the same time, the server side must accept client requests and become an information hub.

Because ice is independent of the platform itself, editing on which platform does not affect other platforms. First, write an slice file to define the service.

Module floorspace

{

Interface callback

{

Void getinput (string content );

};

Dictionary <string, callback *> cachemap;

Interface floor

{

Bool register (string name );

Void setinput (string content );

Void unregister ();

Void setupcallback (callback * CP );

};

};

Callback is used to define the callback service of the client, and floor is used to define the service of the server.

After defining the slice file, such as floor. Ice, use slice2cpp floor. Ice to generate the service. It generates two files, floor. h and floor. cpp, which define the service interface and proxy interface.

A file is required to inherit various services in the floor interface from floor. H, and a file is required to inherit the services in the callback interface from floor. h.

Class floori: virtual public floor

{

Virtual bool register (const string & name, const current & context );

Virtual void setinput (const string & content, const current & context );

Virtual void unregister (const current & context );

Virtual void setupcallback (const callbackprx & PRx, const current & context );

Cachemap m_cache_map;

};

Class callbacki: virtual public callback

{

Public:

Virtual void getinput (const string & content, const current & context );

};

Of course, you need to implement the virtual functions in floori, which is the real location of your service.

Bool floori: Register (const string & name, const current & context)

{

If (m_cache_map.find (name )! = M_cache_map.end ())

Return 0;

Else

M_cache_map [name];

Return 1;

}

Void floori: unregister (const current & context)

{

Context: const_iterator q = context. CTX. Find ("user_name ");

If (Q! = Context. CTX. End ())

{

Cachemap: iterator P;

If (P = m_cache_map.find (Q-> second ))! = M_cache_map.end ())

M_cache_map.erase (P );

}

}

Void floori: setupcallback (const callbackprx & PRx, const current & context)

{

Context: const_iterator P = context. CTX. Find ("user_name ");

If (P! = Context. CTX. End ())

{

M_cache_map [p-> second] = PRx;

}

}

Void floori: setinput (const string & content, const current & context)

{

Context: const_iterator q = context. CTX. Find ("user_name ");

If (Q! = Context. CTX. End ())

{

Cachemap: iterator P;

For (P = m_cache_map.begin (); P! = M_cache_map.end (); ++ P)

{

If (p-> first! = Q-> second)

{

Context CTX;

CTX ["user_name"] = Q-> second;

Try

{

P-> second-> getinput (content, CTX );

}

Catch (connectionrefusedexception E)

{

M_cache_map.erase (P );

Cout <"failed" <Endl;

}

Catch (nullhandleexception E)

{

M_cache_map.erase (P );

Cout <"not sincere" <Endl;

}

}

}

}

}

Callback service definition:

Void callbacki: getinput (const string & content, const current & context)

{

Context: const_iterator q = context. CTX. Find ("user_name ");

If (Q! = Context. CTX. End ())

{

Cout <"[" <q-> second <"say]" <content <Endl;

}

}

In this way, the Service definitions of the server and client in our chat room are completed. The rest is the write server and client, and the server implementation is very simple, because this is the ice framework:

Int serverapp: Run (INT argc, char * argv [])

{

Shutdownoninterrupt ();

Objectadapterptr adapter = communicator ()-> createobjectadapter ("floor. Server ");

Adapter-> Add (New floori, stringtoidentity ("floor "));

Adapter-> activate ();

Communicator ()-> waitforshutdown ();

Return exit_success;

}

Just a few lines of code can achieve network connection and service creation. Client implementation:

Int clientapp: Run (INT argc, char * argv [])

{

Shutdownoninterrupt ();

Ice: propertiesptr properties = communicator ()-> getproperties ();

Const char * Buf = "floor. Proxy ";

String proxy = properties-> getproperty (BUF );

If (proxy. Empty ())

{

Cerr <argv [0] <": properties'" <Buf <"'Not set" <Endl;

Return exit_failure;

}

Cout <proxy <Endl;

Floorprx = floorprx: checkedcast (communicator ()-> stringtoproxy (proxy ));

If (! Floorprx)

{

Cerr <argv [0] <": Invalid proxy" <Endl;

Return exit_failure;

}

String user_name;

Cout <"name :";

Cin> user_name;

Cout <Endl;

If (floorprx-> Register (user_name) = 0)

{

Cout <user_name <"has been registered" <Endl;

Return exit_failure;

}

Ice: objectadapterptr adapter = communicator ()-> createobjectadapter ("floor. Client ");

Adapter-> Add (New callbacki, ice: stringtoidentity ("callbackreceiver "));

Adapter-> activate ();

Context CTX;

CTX ["user_name"] = user_name;

Floorprx = floorprx: uncheckedcast (floorprx-> ice_newcontext (CTX ));

Callbackprx CBP = callbackprx: uncheckedcast (adapter-> createproxy (stringtoidentity ("callbackreceiver ")));

Floorprx-> setupcallback (CBP );

String content;

Cout <"Please input something" <Endl;

Cout <"[" <user_name <"say]";

While (CIN> content)

{

Cout <Endl;

Floorprx-> setinput (content );

Cout <"[" <user_name <"say]";

}

Floorprx-> unregister ();

}

What we do is to send a speech to the server, and the server broadcasts the speech to other users. The function is complete.

Conclusion: Ice frees you from worrying about how the network is connected, how the port is defined, and how the service is implemented. This is exactly what you want. When you know what you want to do, but think of the complexity of network communication, you may have no confidence. Ice just makes it possible. It is a pleasure to learn about ice.

File:
Ice_floor_callback.rar

Size:
10kb

Download:
Download

Transferred from: http://blog.chinaunix.net/u/20057/showart_123629.h...

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.