1 ///////////////////////////////////////////////////////////////////////////////
2 // Name: samples/ipc/baseserver.cpp
3 // Purpose: IPC sample: console server
4 // Author: Anders Larsen
5 // Most of the code was stolen from: samples/ipc/server.cpp
6 // (c) Julian Smart, Jurgen Doornik
9 // Copyright: (c) 2007 Anders Larsen
10 // License: wxWindows licence
11 ///////////////////////////////////////////////////////////////////////////////
13 // ============================================================================
15 // ============================================================================
17 // ----------------------------------------------------------------------------
19 // ----------------------------------------------------------------------------
21 // For compilers that support precompilation, includes "wx.h".
22 #include "wx/wxprec.h"
32 // Settings common to both executables: determines whether
33 // we're using TCP/IP or real DDE.
37 #include "wx/datetime.h"
39 // ----------------------------------------------------------------------------
41 // ----------------------------------------------------------------------------
43 // Define a new application
47 class MyApp
: public wxApp
50 virtual bool OnInit();
59 class MyConnection
: public wxConnection
, public wxTimer
63 virtual ~MyConnection();
65 virtual bool Disconnect() { return wxConnection
::Disconnect(); }
66 virtual bool OnExecute(const wxString
& topic
, const void *data
, size_t size
, wxIPCFormat format
);
67 virtual const void *OnRequest(const wxString
& topic
, const wxString
& item
, size_t *size
, wxIPCFormat format
);
68 virtual bool OnPoke(const wxString
& topic
, const wxString
& item
, const void *data
, size_t size
, wxIPCFormat format
);
69 virtual bool OnStartAdvise(const wxString
& topic
, const wxString
& item
);
70 virtual bool OnStopAdvise(const wxString
& topic
, const wxString
& item
);
71 virtual bool DoAdvise(const wxString
& item
, const void *data
, size_t size
, wxIPCFormat format
);
72 virtual bool OnDisconnect();
73 virtual void Notify();
76 void Log(const wxString
& command
, const wxString
& topic
, const wxString
& item
, const void *data
, size_t size
, wxIPCFormat format
);
82 wxString m_sRequestDate
;
83 char m_achRequestBytes
[3];
86 class MyServer
: public wxServer
92 bool IsConnected() { return m_connection
!= NULL
; };
93 MyConnection
*GetConnection() { return m_connection
; };
94 wxConnectionBase
*OnAcceptConnection(const wxString
& topic
);
97 MyConnection
*m_connection
;
100 // ============================================================================
102 // ============================================================================
106 // ----------------------------------------------------------------------------
108 // ----------------------------------------------------------------------------
112 if ( !wxApp
::OnInit() )
115 delete wxLog
::SetActiveTarget(new wxLogStderr
);
117 // Create a new server
118 m_server
= new MyServer
;
119 if (m_server
->Create("4242"))
121 wxLogMessage(_T("Server 4242 started"));
122 #if wxUSE_DDE_FOR_IPC
123 wxLogMessage(_T("Server uses DDE"));
124 #else // !wxUSE_DDE_FOR_IPC
125 wxLogMessage(_T("Server uses TCP"));
126 #endif // wxUSE_DDE_FOR_IPC/!wxUSE_DDE_FOR_IPC
131 wxLogMessage(_T("Server 4242 failed to start"));
142 // ----------------------------------------------------------------------------
144 // ----------------------------------------------------------------------------
151 MyServer
::~MyServer()
156 wxConnectionBase
*MyServer
::OnAcceptConnection(const wxString
& topic
)
158 wxLogMessage(_T("OnAcceptConnection(\"%s\")"), topic
.c_str());
160 if ( topic
== IPC_TOPIC
)
162 m_connection
= new MyConnection
;
163 wxLogMessage(_T("Connection accepted"));
170 void MyServer
::Disconnect()
174 m_connection
->Disconnect();
177 wxLogMessage(_T("Disconnected client"));
181 // ----------------------------------------------------------------------------
183 // ----------------------------------------------------------------------------
185 MyConnection
::MyConnection()
189 MyConnection
::~MyConnection()
193 bool MyConnection
::OnExecute(const wxString
& topic
,
194 const void *data
, size_t size
, wxIPCFormat format
)
196 Log(_T("OnExecute"), topic
, _T(""), data
, size
, format
);
200 bool MyConnection
::OnPoke(const wxString
& topic
,
201 const wxString
& item
, const void *data
, size_t size
, wxIPCFormat format
)
203 Log(_T("OnPoke"), topic
, item
, data
, size
, format
);
204 return wxConnection
::OnPoke(topic
, item
, data
, size
, format
);
207 const void *MyConnection
::OnRequest(const wxString
& topic
,
208 const wxString
& item
, size_t *size
, wxIPCFormat format
)
211 if (item
== _T("Date"))
213 m_sRequestDate
= wxDateTime
::Now().Format();
214 data
= m_sRequestDate
.c_str();
217 else if (item
== _T("Date+len"))
219 m_sRequestDate
= wxDateTime
::Now().FormatTime() + _T(" ") + wxDateTime
::Now().FormatDate();
220 data
= m_sRequestDate
.c_str();
221 *size
= m_sRequestDate
.Length() + 1;
223 else if (item
== _T("bytes[3]"))
225 data
= m_achRequestBytes
;
226 m_achRequestBytes
[0] = '1'; m_achRequestBytes
[1] = '2'; m_achRequestBytes
[2] = '3';
234 Log(_T("OnRequest"), topic
, item
, data
, *size
, format
);
238 bool MyConnection
::OnStartAdvise(const wxString
& topic
,
239 const wxString
& item
)
241 wxLogMessage(_T("OnStartAdvise(\"%s\",\"%s\")"), topic
.c_str(), item
.c_str());
242 wxLogMessage(_T("Returning true"));
248 bool MyConnection
::OnStopAdvise(const wxString
& topic
,
249 const wxString
& item
)
251 wxLogMessage(_T("OnStopAdvise(\"%s\",\"%s\")"), topic
.c_str(), item
.c_str());
252 wxLogMessage(_T("Returning true"));
258 void MyConnection
::Notify()
260 if (!m_sAdvise
.IsEmpty())
262 wxString s
= wxDateTime
::Now().Format();
263 Advise(m_sAdvise
, s
);
264 s
= wxDateTime
::Now().FormatTime() + _T(" ") + wxDateTime
::Now().FormatDate();
265 Advise(m_sAdvise
, (const char *)s
.c_str(), s
.Length() + 1);
267 #if wxUSE_DDE_FOR_IPC
268 wxLogMessage(_T("DDE Advise type argument cannot be wxIPC_PRIVATE. The client will receive it as wxIPC_TEXT, and receive the correct no of bytes, but not print a correct log entry."));
271 bytes
[0] = '1'; bytes
[1] = '2'; bytes
[2] = '3';
272 Advise(m_sAdvise
, bytes
, 3, wxIPC_PRIVATE
);
273 // this works, but the log treats it as a string now
274 // m_connection->Advise(m_connection->m_sAdvise, bytes, 3, wxIPC_TEXT );
278 void MyConnection
::Log(const wxString
& command
, const wxString
& topic
,
279 const wxString
& item
, const void *data
, size_t size
, wxIPCFormat format
)
282 if (topic
.IsEmpty() && item
.IsEmpty())
283 s
.Printf(_T("%s("), command
.c_str());
284 else if (topic
.IsEmpty())
285 s
.Printf(_T("%s(\"%s\","), command
.c_str(), item
.c_str());
286 else if (item
.IsEmpty())
287 s
.Printf(_T("%s(\"%s\","), command
.c_str(), topic
.c_str());
289 s
.Printf(_T("%s(\"%s\",\"%s\","), command
.c_str(), topic
.c_str(), item
.c_str());
295 #if !wxUSE_UNICODE || wxUSE_UNICODE_UTF8
296 wxLogMessage(_T("%s\"%s\",%d)"), s
.c_str(), data
, size
);
298 wxLogMessage(_T("%s\"%s\",%d)"), s
.c_str(), wxConvUTF8
.cMB2WC((const char*)data
), size
);
304 char *bytes
= (char *)data
;
305 wxLogMessage(_T("%s'%c%c%c',%d)"), s
.c_str(), bytes
[0], bytes
[1], bytes
[2], size
);
308 wxLogMessage(_T("%s...,%d)"), s
.c_str(), size
);
311 wxLogMessage(_T("%s[invalid data],%d)"), s
.c_str(), size
);
314 wxLogMessage(_T("%s[unknown data],%d)"), s
.c_str(), size
);
319 bool MyConnection
::DoAdvise(const wxString
& item
, const void *data
, size_t size
, wxIPCFormat format
)
321 Log(_T("Advise"), _T(""), item
, data
, size
, format
);
322 return wxConnection
::DoAdvise(item
, data
, size
, format
);
325 bool MyConnection
::OnDisconnect()
327 wxLogMessage(_T("OnDisconnect()"));