git-svn-id: https://svn.wxwidgets.org/svn/wx/wxWidgets/trunk@54611 c3d73ce0-8a6f-49c7-b76d-6d57e0e08775
		
			
				
	
	
		
			394 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
			
		
		
	
	
			394 lines
		
	
	
		
			11 KiB
		
	
	
	
		
			C++
		
	
	
	
	
	
/////////////////////////////////////////////////////////////////////////////
 | 
						|
// Name:        server.cpp
 | 
						|
// Purpose:     IPC sample: server
 | 
						|
// Author:      Julian Smart
 | 
						|
// Modified by: Jurgen Doornik
 | 
						|
// Created:     25/01/99
 | 
						|
// RCS-ID:      $Id$
 | 
						|
// Copyright:   (c) Julian Smart
 | 
						|
// Licence:     wxWindows licence
 | 
						|
/////////////////////////////////////////////////////////////////////////////
 | 
						|
 | 
						|
// ============================================================================
 | 
						|
// declarations
 | 
						|
// ============================================================================
 | 
						|
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
// headers
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
 | 
						|
// For compilers that support precompilation, includes "wx.h".
 | 
						|
#include "wx/wxprec.h"
 | 
						|
 | 
						|
#ifdef __BORLANDC__
 | 
						|
    #pragma hdrstop
 | 
						|
#endif
 | 
						|
 | 
						|
#ifndef WX_PRECOMP
 | 
						|
    #include "wx/wx.h"
 | 
						|
#endif
 | 
						|
 | 
						|
// Settings common to both executables: determines whether
 | 
						|
// we're using TCP/IP or real DDE.
 | 
						|
#include "ipcsetup.h"
 | 
						|
 | 
						|
#if !defined(__WXMSW__) && !defined(__WXPM__)
 | 
						|
    #include "../sample.xpm"
 | 
						|
#endif
 | 
						|
 | 
						|
#include "server.h"
 | 
						|
#include "wx/textdlg.h"
 | 
						|
#include "wx/datetime.h"
 | 
						|
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
// wxWin macros
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
 | 
						|
IMPLEMENT_APP(MyApp)
 | 
						|
 | 
						|
BEGIN_EVENT_TABLE(MyFrame, wxFrame)
 | 
						|
    EVT_CLOSE( MyFrame::OnClose )
 | 
						|
 | 
						|
    EVT_BUTTON( ID_START,          MyFrame::OnStart )
 | 
						|
    EVT_CHOICE( ID_SERVERNAME,     MyFrame::OnServerName )
 | 
						|
    EVT_BUTTON( ID_DISCONNECT,     MyFrame::OnDisconnect )
 | 
						|
    EVT_BUTTON( ID_ADVISE,         MyFrame::OnAdvise )
 | 
						|
END_EVENT_TABLE()
 | 
						|
 | 
						|
 | 
						|
// ============================================================================
 | 
						|
// implementation
 | 
						|
// ============================================================================
 | 
						|
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
// MyApp
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
 | 
						|
bool MyApp::OnInit()
 | 
						|
{
 | 
						|
    if ( !wxApp::OnInit() )
 | 
						|
        return false;
 | 
						|
 | 
						|
    // Create the main frame window
 | 
						|
    m_frame = new MyFrame(NULL, "Server");
 | 
						|
    m_frame->Show(true);
 | 
						|
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
// MyFrame
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
 | 
						|
// Define my frame constructor
 | 
						|
MyFrame::MyFrame(wxFrame *frame, const wxString& title)
 | 
						|
       : wxFrame(frame, wxID_ANY, title, wxDefaultPosition, wxSize(400, 300))
 | 
						|
{
 | 
						|
#if wxUSE_STATUSBAR
 | 
						|
    CreateStatusBar();
 | 
						|
#endif // wxUSE_STATUSBAR
 | 
						|
 | 
						|
    SetIcon(wxICON(sample));
 | 
						|
 | 
						|
    m_server = NULL;
 | 
						|
 | 
						|
    wxPanel * const panel = new wxPanel(this);
 | 
						|
 | 
						|
    wxBoxSizer * const sizerMain = new wxBoxSizer( wxVERTICAL );
 | 
						|
 | 
						|
    wxFlexGridSizer * const sizerCmds = new wxFlexGridSizer( 2, 0, 0 );
 | 
						|
    sizerCmds->AddGrowableCol( 1 );
 | 
						|
 | 
						|
    wxButton *btn;
 | 
						|
 | 
						|
    btn = new wxButton(panel, ID_START, "&Start Server");
 | 
						|
    sizerCmds->Add(btn, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5);
 | 
						|
 | 
						|
    const wxString choices[] = { IPC_SERVICE, "..." };
 | 
						|
    wxChoice * const choice = new wxChoice
 | 
						|
                                  (
 | 
						|
                                    panel,
 | 
						|
                                    ID_SERVERNAME,
 | 
						|
                                    wxDefaultPosition, wxSize(100, -1),
 | 
						|
                                    WXSIZEOF(choices), choices
 | 
						|
                                  );
 | 
						|
    sizerCmds->Add(choice, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5);
 | 
						|
 | 
						|
    btn = new wxButton(panel, ID_DISCONNECT, "&Disconnect Client");
 | 
						|
    sizerCmds->Add(btn, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5);
 | 
						|
    sizerCmds->AddSpacer(20);
 | 
						|
 | 
						|
    btn = new wxButton( panel, ID_ADVISE, "&Advise");
 | 
						|
    sizerCmds->Add(btn, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5);
 | 
						|
    sizerCmds->AddSpacer(20);
 | 
						|
 | 
						|
    sizerMain->Add(sizerCmds, 0, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5);
 | 
						|
 | 
						|
    wxStaticBoxSizer * const
 | 
						|
        sizerLog = new wxStaticBoxSizer(wxVERTICAL, panel, "Server &log");
 | 
						|
 | 
						|
    wxTextCtrl * const textLog = new wxTextCtrl
 | 
						|
                                 (
 | 
						|
                                    panel,
 | 
						|
                                    wxID_ANY,
 | 
						|
                                    "",
 | 
						|
                                    wxDefaultPosition, wxSize(500, 140),
 | 
						|
                                    wxTE_MULTILINE
 | 
						|
                                 );
 | 
						|
    sizerLog->Add(textLog, 1, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5);
 | 
						|
 | 
						|
    sizerMain->Add(sizerLog, 1, wxGROW|wxALIGN_CENTER_VERTICAL|wxALL, 5);
 | 
						|
 | 
						|
    panel->SetSizer(sizerMain);
 | 
						|
    sizerMain->SetSizeHints(panel);
 | 
						|
    SetClientSize(panel->GetSize());
 | 
						|
 | 
						|
    GetServername()->SetSelection(0);
 | 
						|
    wxLogTextCtrl *logWindow = new wxLogTextCtrl(textLog);
 | 
						|
    delete wxLog::SetActiveTarget(logWindow);
 | 
						|
    wxLogMessage("Click on Start to start the server");
 | 
						|
    UpdateUI();
 | 
						|
}
 | 
						|
 | 
						|
void MyFrame::UpdateUI()
 | 
						|
{
 | 
						|
    GetStart()->Enable(m_server == NULL);
 | 
						|
    GetServername()->Enable(m_server == NULL);
 | 
						|
    GetAdvise()->Enable(m_server && m_server->CanAdvise());
 | 
						|
    GetDisconnect()->Enable(m_server && m_server->IsConnected());
 | 
						|
}
 | 
						|
 | 
						|
void MyFrame::OnClose(wxCloseEvent& event)
 | 
						|
{
 | 
						|
    if (m_server)
 | 
						|
    {
 | 
						|
        delete m_server;
 | 
						|
        m_server = NULL;
 | 
						|
    }
 | 
						|
    event.Skip();
 | 
						|
}
 | 
						|
 | 
						|
void MyFrame::OnStart(wxCommandEvent& WXUNUSED(event))
 | 
						|
{
 | 
						|
    // Create a new server
 | 
						|
    m_server = new MyServer;
 | 
						|
    wxString servername = GetServername()->GetStringSelection();
 | 
						|
    if (m_server->Create(servername))
 | 
						|
    {
 | 
						|
        wxLogMessage("Server %s started", servername);
 | 
						|
  #if wxUSE_DDE_FOR_IPC
 | 
						|
        wxLogMessage("Server uses DDE");
 | 
						|
  #else // !wxUSE_DDE_FOR_IPC
 | 
						|
        wxLogMessage("Server uses TCP");
 | 
						|
  #endif // wxUSE_DDE_FOR_IPC/!wxUSE_DDE_FOR_IPC
 | 
						|
    }
 | 
						|
    else
 | 
						|
    {
 | 
						|
        wxLogMessage("Server %s failed to start", servername);
 | 
						|
        delete m_server;
 | 
						|
        m_server = NULL;
 | 
						|
    }
 | 
						|
    UpdateUI();
 | 
						|
}
 | 
						|
 | 
						|
void MyFrame::OnServerName( wxCommandEvent& WXUNUSED(event) )
 | 
						|
{
 | 
						|
    if ( GetServername()->GetStringSelection() == "..." )
 | 
						|
    {
 | 
						|
        wxString s = wxGetTextFromUser
 | 
						|
                     (
 | 
						|
                        "Specify the name of the server",
 | 
						|
                        "Server Name",
 | 
						|
                        "",
 | 
						|
                        this
 | 
						|
                     );
 | 
						|
 | 
						|
        if ( !s.empty() && s != IPC_SERVICE )
 | 
						|
        {
 | 
						|
            GetServername()->Insert(s, 0);
 | 
						|
            GetServername()->SetSelection(0);
 | 
						|
        }
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
void MyFrame::Disconnect()
 | 
						|
{
 | 
						|
    m_server->Disconnect();
 | 
						|
    UpdateUI();
 | 
						|
}
 | 
						|
 | 
						|
void MyFrame::OnDisconnect(wxCommandEvent& WXUNUSED(event))
 | 
						|
{
 | 
						|
    Disconnect();
 | 
						|
}
 | 
						|
 | 
						|
void MyFrame::OnAdvise(wxCommandEvent& WXUNUSED(event))
 | 
						|
{
 | 
						|
    m_server->Advise();
 | 
						|
}
 | 
						|
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
// MyServer
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
 | 
						|
MyServer::MyServer() : wxServer()
 | 
						|
{
 | 
						|
    m_connection = NULL;
 | 
						|
}
 | 
						|
 | 
						|
MyServer::~MyServer()
 | 
						|
{
 | 
						|
    Disconnect();
 | 
						|
}
 | 
						|
 | 
						|
wxConnectionBase *MyServer::OnAcceptConnection(const wxString& topic)
 | 
						|
{
 | 
						|
    wxLogMessage("OnAcceptConnection(\"%s\")", topic);
 | 
						|
 | 
						|
    if ( topic == IPC_TOPIC )
 | 
						|
    {
 | 
						|
        m_connection = new MyConnection();
 | 
						|
        wxGetApp().GetFrame()->UpdateUI();
 | 
						|
        wxLogMessage("Connection accepted");
 | 
						|
        return m_connection;
 | 
						|
    }
 | 
						|
    //else: unknown topic
 | 
						|
 | 
						|
    wxLogMessage("Unknown topic, connection refused");
 | 
						|
    return NULL;
 | 
						|
}
 | 
						|
 | 
						|
void MyServer::Disconnect()
 | 
						|
{
 | 
						|
    if ( m_connection )
 | 
						|
    {
 | 
						|
        delete m_connection;
 | 
						|
        m_connection = NULL;
 | 
						|
        wxGetApp().GetFrame()->UpdateUI();
 | 
						|
        wxLogMessage("Disconnected client");
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
void MyServer::Advise()
 | 
						|
{
 | 
						|
    if ( CanAdvise() )
 | 
						|
    {
 | 
						|
        const wxDateTime now = wxDateTime::Now();
 | 
						|
 | 
						|
        m_connection->Advise(m_connection->m_advise, now.Format());
 | 
						|
 | 
						|
        const wxString s = now.FormatTime() + " " + now.FormatDate();
 | 
						|
        m_connection->Advise(m_connection->m_advise, s.mb_str(), wxNO_LEN);
 | 
						|
 | 
						|
#if wxUSE_DDE_FOR_IPC
 | 
						|
        wxLogMessage("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.");
 | 
						|
#endif
 | 
						|
        char bytes[3] = { '1', '2', '3' };
 | 
						|
        m_connection->Advise(m_connection->m_advise, bytes, 3, wxIPC_PRIVATE);
 | 
						|
    }
 | 
						|
}
 | 
						|
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
// MyConnection
 | 
						|
// ----------------------------------------------------------------------------
 | 
						|
 | 
						|
bool
 | 
						|
MyConnection::OnExecute(const wxString& topic,
 | 
						|
                        const void *data,
 | 
						|
                        size_t size,
 | 
						|
                        wxIPCFormat format)
 | 
						|
{
 | 
						|
    Log("OnExecute", topic, "", data, size, format);
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool
 | 
						|
MyConnection::OnPoke(const wxString& topic,
 | 
						|
                     const wxString& item,
 | 
						|
                     const void *data,
 | 
						|
                     size_t size,
 | 
						|
                     wxIPCFormat format)
 | 
						|
{
 | 
						|
    Log("OnPoke", topic, item, data, size, format);
 | 
						|
    return wxConnection::OnPoke(topic, item, data, size, format);
 | 
						|
}
 | 
						|
 | 
						|
const void *
 | 
						|
MyConnection::OnRequest(const wxString& topic,
 | 
						|
                        const wxString& item,
 | 
						|
                        size_t *size,
 | 
						|
                        wxIPCFormat format)
 | 
						|
{
 | 
						|
    *size = 0;
 | 
						|
 | 
						|
    wxString afterDate;
 | 
						|
    if ( item.StartsWith("Date", &afterDate) )
 | 
						|
    {
 | 
						|
        const wxDateTime now = wxDateTime::Now();
 | 
						|
 | 
						|
        if ( afterDate.empty() )
 | 
						|
        {
 | 
						|
            m_requestData = now.Format();
 | 
						|
            *size = wxNO_LEN;
 | 
						|
        }
 | 
						|
        else if ( afterDate == "+len" )
 | 
						|
        {
 | 
						|
            m_requestData = now.FormatTime() + " " + now.FormatDate();
 | 
						|
            *size = strlen(m_requestData.mb_str()) + 1;
 | 
						|
        }
 | 
						|
    }
 | 
						|
    else if ( item == "bytes[3]" )
 | 
						|
    {
 | 
						|
        m_requestData = "123";
 | 
						|
        *size = 3;
 | 
						|
    }
 | 
						|
 | 
						|
    if ( !*size )
 | 
						|
    {
 | 
						|
        wxLogMessage("Unknown request for \"%s\"", item);
 | 
						|
        return NULL;
 | 
						|
    }
 | 
						|
 | 
						|
    const void * const data = m_requestData.mb_str();
 | 
						|
    Log("OnRequest", topic, item, data, *size, format);
 | 
						|
    return data;
 | 
						|
}
 | 
						|
 | 
						|
bool MyConnection::OnStartAdvise(const wxString& topic, const wxString& item)
 | 
						|
{
 | 
						|
    wxLogMessage("OnStartAdvise(\"%s\", \"%s\")", topic, item);
 | 
						|
    wxLogMessage("Returning true");
 | 
						|
    m_advise = item;
 | 
						|
    wxGetApp().GetFrame()->UpdateUI();
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool MyConnection::OnStopAdvise(const wxString& topic, const wxString& item)
 | 
						|
{
 | 
						|
    wxLogMessage("OnStopAdvise(\"%s\",\"%s\")", topic, item);
 | 
						|
    wxLogMessage("Returning true");
 | 
						|
    m_advise.clear();
 | 
						|
    wxGetApp().GetFrame()->UpdateUI();
 | 
						|
    return true;
 | 
						|
}
 | 
						|
 | 
						|
bool
 | 
						|
MyConnection::DoAdvise(const wxString& item,
 | 
						|
                       const void *data,
 | 
						|
                       size_t size,
 | 
						|
                       wxIPCFormat format)
 | 
						|
{
 | 
						|
    Log("Advise", "", item, data, size, format);
 | 
						|
    return wxConnection::DoAdvise(item, data, size, format);
 | 
						|
}
 | 
						|
 | 
						|
bool MyConnection::OnDisconnect()
 | 
						|
{
 | 
						|
    wxLogMessage("OnDisconnect()");
 | 
						|
    wxGetApp().GetFrame()->Disconnect();
 | 
						|
    return true;
 | 
						|
}
 |