One message prompts the development history of the pallet Program (using socket technology, with source code) I

Source: Internet
Author: User

In one of my J2EE projects, when a person's task arrives, we display the task on a JSP page, prompting the user to process the task.
We use poll databases to monitor tasks in real time. Table user_message stores user tasks. The table structure is as follows:
Create Table user_message
(
Message_id number (9) Not null,
Task_id varchar2 (100 ),
User_code varchar2 (10 ),
Task_name varchar2 (50 ),
Is_read varchar2 (1 ),
Create_time date,
Task_state varchar2 (10 ),
Create_man varchar2 (10 ),
Send_man varchar2 (10 ),
Pre_task_name varchar2 (50 ),
Serial_code number (11 ),
Message_title varchar2 (200)
)
When is_read = 'F', it is a new task.
This solution has the following drawbacks:
1: You must open the page to view the task;
2: each client needs to be polling. When many users have large database loads;
So I made an auxiliary message reminder tool. When the task arrives, I sent a prompt message in the system tray area, similar to QQ.
The solution is as follows:
Use socket technology to write client and server programs. As the message server, the server uses the database round-robin method to monitor the user_message table in real time.
Send the new task message to the client. The client identifies whether the message is a "my" message. If it is a "My message", the message will flash in the system tray area. Click the blinking icon, you can see the message title and click under the Message Title
You can open the page to enter the J2EE system.
Now let's use C ++ builder to do this little stuff step by step:
The knowledge to be prepared is as follows:
I. Use your own message communication protocol
Ii. socket programming
Iii. How to Implement system pallets
4. How to package a record in the database and send it to the client?
We solve the problem one by one:
I. The message communication protocol is as follows:
MSG. h
/*
* Create Date: 2004-12-01
* Create by: Li chunlei
* Purpose: custom message structure for the Protocol:
* Messageinfo: task message
* Msgtype message header: 0xa logon succeeded, 0xb Logon Failed, 0xc working message, and 0xd task end identifier
* Logininfo: Logon Message
*/

//------------------------------------------------------------------------------

Struct messageinfo {// message structure
Int msgtype; // message header: 0xa logon succeeded, 0xb Logon Failed, 0xc working message, and 0xd task end identifier
Char messageid [10]; // task no.
Char usrcode [10]; // User Account
// Char tastname [50]; // Task Name
Char tastname [200]; // Task Name
Char creattime [20]; // time
};

Struct logininfo {// login information
Char PWD [20]; // User Password
Char userid [30]; // user ID
};
//------------------------------------------------------------------------------
The message sent by the server only uses the messageinfo structure (check whether the login is successful and the task message is sent), and the client sends the login information (logininfo) only once)
To the server. Other times only accept messages sent from the server.

Ii. socket programming
If you haven't used socket programming, it doesn't matter. Learn now:
C ++ Builder provides the Internet Suite. The tclientsocket and tserversocket components encapsulate windows APIs and greatly simplify WinSock programming.
To transmit data over the Internet, at least one socket is required, one socket is on the client, and the other socket is on the server. In fact, the tclientsocket and tserversocket components are not socket objects,
Its socket property will return their respective socket objects. Tclientsocket is used to process socket connections between the client and the server, and tserversocket is used to process socket connections sent from the client,
Once both the client and the server are connected to a socket, the client and the server can communicate with each other.
Let's make a small example:
---- Create a new project and create the user interface of the application:
---- 1. switch the component page to the Internet page and place a tserversocket component and a tclientsocket component on the form. In this way, the application can be either a TCP/IP server or a TCP/IP client.
Set the port attribute to the same value (for example, 1000), and set the connection type between sockets to nonblocking (non-blocking mode ).
---- 2. place two tmemo components on the form to display the conversation content of both parties, and set the readonly attribute of memo2 to true.
---- 3. put a panel component on the top of the form and put three buttons on it: listener (btnlisten), connection (btnconnect), and disconnection (btndisconnect) to start the corresponding operation.
---- 4. Put a statusbar component at the bottom of the form, set its simplepanel attribute to true, and change the status bar information in the corresponding event handler so that users can know the connection status at any time.
---- Open the header file and add two private members in the private segment of the Form class: bool isserver and string server. When both parties communicate, they need to run the chat program at the same time. The isserver is used to determine which
The chat program is on the server side and the server is used to store the Host Name of the server. The constructor for creating a form class is as follows:
_ Fastcall tform1: tform1 (tcomponent * owner)
: Tform (owner)
{
Isserver = false;
Server = "localhost ";
}
---- The server is set to localhost by default, so that the program can be debugged on a single machine that is not connected to the Internet. In the Windows subdirectory, you can find the hosts. Sam file in
The local IP address 127.0.0.1 has been defined as the host name: localhost.
Void _ fastcall tform1: formcreate (tobject * sender)
{
Btndisconnect-> enabled = false;
}
---- After the program runs, if you press the "listener" button, set the program as a server. In this case, set the active attribute of tserversocket to true so that the server automatically enters the listening status.
Void _ fastcall tform1: btnlistenclick (tobject * sender)
{
Clientsocket1-> active = false;
Serversocket1-> active = true;
Statusbar1-> simpletext = "listening ...";
Btnlisten-> enabled = false;
Btnconnect-> enabled = false;
}

---- When the user presses the "connection" button, the program will pop up a dialog box asking the user to enter the host name of the server to be connected, and then establish a connection.
Void _ fastcall tform1: btnconnectclick (tobject * sender)
{
If (inputquery ("connect to server", "Enter server address:", server )){
If (server. Length ()> 0 ){
Clientsocket1-> host = server;
Clientsocket1-> active = true;
Btnlisten-> enabled = false;
Btnconnect-> enabled = false;
Btndisconnect-> enabled = true;
}
}
}

---- After the user initiates a connection request, the client will trigger the oncreate event. The program first displays the connection information in the status bar, then clears memo2 that shows the conversation content of the other party, and prepares to start the conversation.
Void _ fastcall tform1: clientsocket1connect (tobject * sender,
Tcustomwinsocket * socket)
{
Statusbar1-> simpletext = "connect to:" + server;
Memo2-> lines-> clear ();
}
---- The onaccept event is triggered when the server accepts the client's request. In this event handler, set the isserver variable on the server to true and prepare to start the conversation.
Void _ fastcall tform1: serversocket1accept (
Tobject * sender,
Tcustomwinsocket * socket)
{
Memo2-> lines-> clear ();
Isserver = true;
Statusbar1-> simpletext = "connect :"
+ Socket-> remoteaddress;
}
---- After the connection is established, both parties can enter the conversation content in memo1 to start the conversation. Press enter to send the text of the row. Server socket connections
Attribute returns an array consisting of connections currently active on the server.
Void _ fastcall tform1: memo1keydown (
Tobject * sender, word & Key,
Tshiftstate shift)
{
If (Key = vk_return ){
If (isserver)
Serversocket1-> socket-> connections [0]-> sendtext (
Memo1-> lines-> strings [memo1-> lines-> count-1]);
Else
Clientsocket1-> socket-> sendtext (
Memo1-> lines-> strings [memo1-> lines-> count-1]);
}
}

---- In this example, we adopt a non-blocking transmission mode. When one party performs write operations, the other Party triggers the onread event (client) or onclientread event (server ), the processing programs of these two events only add the received content to the end of memo2.
Memo2-> lines-> Add (socket-> receivetext ());

---- If you click the "Disconnect" button after the user establishes a connection, the connection between the client and the server will be disconnected, the server will trigger the onclientdisconnect event, and the client will trigger the ondisconnect event, at this time, the server should return to the listening status, waiting for the user's connection; and the client will return to the status before the connection, waiting for the user to establish a connection again, if there is more than one server, you can choose to connect to another server.
Void _ fastcall tform1: btndisconnectclick (
Tobject * sender)
{
Clientsocket1-> close ();
}
Void _ fastcall tform1: serversocket1clientdisconnect (
Tobject * sender,
Tcustomwinsocket * socket)
{
Statusbar1-> simpletext = "listening ...";
}
Void _ fastcall tform1: clientsocket1disconnect (
Tobject * sender, tcustomwinsocket * socket)
{
Btnlisten-> enabled = true;
Btnconnect-> enabled = true;
Btndisconnect-> enabled = false;
Statusbar1-> simpletext = "";
}
---- In addition, the error capture mechanism should be added on the client. When the user enters an Invalid server name or the server is not in the listening status, the user can be notified in a timely manner.
Void _ fastcall tform1: clientsocke
T1error (tobject * sender,
Tcustomwinsocket * socket,
Terrorevent errorevent, Int & errorcode)
{
Statusbar1-> simpletext = "unable to connect:
"+ Socket-> remotehost;
Errorcode = 0;
}
After the preceding steps are completed, the socket can run. Is there no imaginary difficulty?

Iii. BCB provides a simple implementation method for pallets:
Let's compile a simple tary program:
1. Create a project and add a trayicon component, a popupmenu component, and an imagelist component. Their name attributes all use the default names: trayicon1,
Popupmenu1 and imagelist1.
2. Set the attributes of trayicon1 as follows:
Attribute Value
Animate true
Animateinterva 1000
Hide true
Hint tary demo
Iconindex 0
Icons imagelist1
Name trayicon1
Popupmenu popupmenu1
Popupmenuon imrightclickup
Restoreon imdoubleclick
Visible true
3. Double-click popupmenu1 to bring up the menu designer and add several menu items as needed.
4. Double-click imagelist1 and add the supported images (*. ICO, *. BMP ).
At this point, there is no need to write a program code, and a simple tary program is ready. Press F9 to compile and run the program. If you move the mouse over tary, the prompt message "tary demo program" appears;
Right-click tary and choose popmenu1 from the shortcut menu. Press the Minimize button in the program window to hide the title bar on the taskbar. Double-click tary to minimize the recovery program;
In addition, the tary icon changes at a speed of 1000 milliseconds (1 second. Is it easy enough ?!

4. How to package a record in the database and send it to the client?
We put a record in the database in a struct, and then send the struct.
The following is a simple example:
. H
Struct tuserinfo
{
Int no; // User Group
Char usrid [20]; // User Account
};

. Cpp
Void _ fastcall tform1: button1click (tobject * sender)
{Tuserinfo * TST = new tuserinfo [2];
Tst [0]. No = 1;
Tst [1]. No = 2;
String TMP = "normal ";
Memcpy (TST [0]. usrid, TMP. c_str (), TMP. Length () + 1 );
TMP = "abnormal ";
Memcpy (TST [1]. usrid, TMP. c_str (), TMP. Length () + 1 );
Clientsocket1-> socket-> sendbuf (TST, 24 );
Delete TST ;}
Void _ fastcall tform1: serversocket1clientread (tobject * sender,
Tcustomwinsocket * socket)
{
Tuserinfo * TST = new tuserinfo [2];
Socket-> receivebuf (TST, 24 );
Showmessage (TST [0]. usrid );
Showmessage (TST [1]. usrid );
}
The above example is very simple and can implement sending of struct, but there is a small problem:
If you want to upload two records, you must use sendbuf (TST, 24*2); then, you must use receivebuf (TST, 24*2) to accept the record );
I am not sure about the number of messages I send, and there are only a few messages. Is there any way I can send them as much as I receive?
In fact, it is also a simple solution:
Send only one struct at a time, and use the for loop to send it out.

After the above technical preparations in 1234, the implementation of the message reminder tool is clear, but the workload is a problem.
In the message prompting tool, I use ADO to access the database.
In addition, to facilitate implementation at the customer's end, I adopted the configuration file. The program first reads the configuration file and then runs it.

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.