ZeroC—ICE分布式数据同步Demo

环境介绍:

操作系统:Windows

数据库:MySQL 5.6

IDE:VS2012

ICE版本:3.5.0

MySQL Lib版本:5.6.12

 

配置文件:

客户端配置文件 info.conf

# IP和端口
ServerIP = 127.0.0.1
ServerPort = 10000

# DateBase信息
DataBase = demoice
Table = demo
HostName = 127.0.0.1
SqlName = root
SqlPwd = *****


服务器配置文件 serverInfo.conf

# DateBase信息
DataBase = demoICE
Table = syn
HostName = 127.0.0.1
SqlName = root
SqlPwd = ******


 

 

 

数据库脚本:

CREATE TABLE demo(
  name VARCHAR(20) PRIMARY KEY,
  pwd VARCHAR(20) NOT NULL
);

CREATE TABLE syn(
  name VARCHAR(20) PRIMARY KEY,
  pwd VARCHAR(20) NOT NULL
);

 

demo为源数据,syn为同步目标

 

Slice文件:

DBOperator.ice

// **********************************************************************
//
// Author: X_White
//
// **********************************************************************

#pragma once

module dbOperator {
	interface DBOprtr {
		int synDropTab();
		int synAllData();
		int synRowData();
		int synSingleData(string s);
		int transmitData(string s, string index);
	};
};


 

客户端:

Client.cpp

// **********************************************************************
//
// Copyright (c) 2003-2013 ZeroC, Inc. All rights reserved.
//
// This copy of Ice is licensed to you under the terms described in the
// ICE_LICENSE file included in this distribution.
//
// **********************************************************************

#include <Ice/Ice.h>
#include <Printer.h>
#include <DBOperator.h>

#include <cstdio>
#include <iostream>
#include <cstring>
#include <time.h>
#include <WinSock2.h>
#include <mysql.h>
#include <vector>

#pragma comment(lib, "libmysql.lib")

using namespace std;
using namespace Demo;
using namespace dbOperator;

typedef struct synData {
	int count;
	char data[20][20];
}synData;

void ice_strcpy(char *src, char *des) {
	size_t i;
	size_t len1 = strlen(src);
	size_t len2 = strlen(des);
	for(i = 0; i < len2; i++) {
		src[i] = des[i];
	}
	src[i] = '\0';
}

int writeLog() {
	return 0;
}

/*
 * Author:X_White
 * initConf读取配置文件info.conf 并返回serverIP、端口号、数据库dbName、表名
 *
*/
int initConf(char *desIP, char *desPort, char *dbName, char *tableName, char *hostName, char *sqlName, char *sqlPwd) {
	FILE *conffp;
	errno_t err;
	char buf[1024];
	err = freopen_s(&conffp, "../conf/info.conf", "r", stdin);
	if(err != 0) {
		writeLog();
		exit(1);
	}
	while(gets_s(buf)) {
		if('#' == buf[0]) continue;
		char n1[128], n2[128], equ[128];
		memset(n1, 0, sizeof(n1));
		memset(n2, 0, sizeof(n2));
		sscanf_s(buf, "%s %s %s", n1, sizeof(n1), equ, sizeof(equ) , n2, sizeof(n2));
//		printf("%s %s\n", tmp, num);
		if(!strcmp(n1, "ServerIP")) {
			ice_strcpy(desIP, n2);
		}
		else if(!strcmp(n1, "ServerPort")) {
			ice_strcpy(desPort, n2);
		}
		else if(!strcmp(n1, "DataBase")) {
			ice_strcpy(dbName, n2);
		}
		else if(!strcmp(n1, "Table")) {
			ice_strcpy(tableName, n2);
		}
		else if(!strcmp(n1, "HostName")) {
			ice_strcpy(hostName, n2);
		}
		else if(!strcmp(n1, "SqlName")) {
			ice_strcpy(sqlName, n2);
		}
		else if(!strcmp(n1, "SqlPwd")) {
			ice_strcpy(sqlPwd, n2);
		}
	}
	return 0;
}

/*
 * Author:X_White
 * sql_init访问mysql,并取出tableName下所有数据
 *
*/
vector<synData> sql_init(char *dbName, char *tableName, char *hostName, char *sqlName, char *sqlPwd) {
	MYSQL *conn = NULL;
	MYSQL_RES *res;
	MYSQL_ROW row;
	vector<synData> vRet;
	char sql[256];
	
	conn = mysql_init(NULL);
	if(!conn) {
		fprintf(stderr, "mysql_init failed\n");
		exit(1);
	}
	conn = mysql_real_connect(conn, hostName, sqlName, sqlPwd, dbName, 0, NULL, 0);
	if(!conn) {
		fprintf(stderr, "mysql_real_connect failed\n");
		exit(1);
	}
	memset(sql, 0, sizeof(sql));
	sprintf_s(sql, "SELECT * FROM %s", tableName);
	if(mysql_query(conn, sql)) {
		fprintf(stderr, "mysql_query failed\n");
		exit(1);
	}
	if(!(res = mysql_store_result(conn))) {
		fprintf(stderr, "Could not get result\n");
		exit(1);
	}

	while(row = mysql_fetch_row(res)) {
		unsigned int count = mysql_field_count(conn);
		unsigned int index = 0;
		struct synData synInfo;
		synInfo.count = count;
		while(index < count) {
			printf("%s ", row[index]);
			ice_strcpy(synInfo.data[index], row[index]);
			index++;
		}
		vRet.push_back(synInfo);
		printf("\n");
	}
	mysql_free_result(res);
	mysql_close(conn);
	return vRet;
}


/*
 * Author: X_White
 * 使用:
 *		1. main 直接同步所有数据
 *		2. main -s sql 同步该条语句
 *       
*/

int main(int argc, char * argv[]) {
    int status = 0;
	Ice::CommunicatorPtr ic;

	char serverIP[128], serverPort[128];
	char dbName[128], tableName[128], hostName[128], sqlName[128], sqlPwd[128];
	char iceProxyString[128] = "SimplePrinter:default -h ";
	char iceProxyDB[128] = "DBOperator:default -h ";
	vector<synData> iceSynData;

	initConf(serverIP, serverPort, dbName, tableName, hostName, sqlName, sqlPwd);
	strcat_s(iceProxyString, serverIP);
	strcat_s(iceProxyString, " -p ");
	strcat_s(iceProxyString, serverPort);

	strcat_s(iceProxyDB, serverIP);
	strcat_s(iceProxyDB, " -p ");
	strcat_s(iceProxyDB, serverPort);
//	printf("%s\n", iceProxyString);

	iceSynData = sql_init(dbName, tableName, hostName, sqlName, sqlPwd);

    try {
        ic = Ice::initialize(argc, argv);
        Ice::ObjectPrx base = ic->stringToProxy(iceProxyString);
		Ice::ObjectPrx dbBase = ic->stringToProxy(iceProxyDB);
        PrinterPrx printer = PrinterPrx::checkedCast(base);
		DBOprtrPrx dbOpAgent = DBOprtrPrx::checkedCast(dbBase);
        if(!printer) {
            throw "Invalid proxy printer";
        }
		if(!dbOpAgent) {
			throw "Invalid proxy dbOpAgent";
		}
//      printer->printString("Hello World!");
/*
 * Author: X_White
 * 远程代理操作数据库
*/
		if(1 == argc) {			
			int i, j;
			i = 0;
//			dbOpAgent->transmitCount(iceSynData[0].count);
			dbOpAgent->synDropTab();
			for(vector<synData>::iterator it = iceSynData.begin(); it != iceSynData.end(); it++, i++) {
				for(j = 0; j < iceSynData[0].count; j++) {
					char tmp[256];
					sprintf_s(tmp, "%d", j);
					string str(tmp);
					dbOpAgent->transmitData(iceSynData[i].data[j], str);
				}
				dbOpAgent->synRowData();
			}
		}
		else if(3 == argc) {
			if(!strcmp(argv[1], "-s")) {
				dbOpAgent->synSingleData(argv[2]);
			}
			else {
				fprintf(stderr, "Arguments error\n");
				fprintf(stderr, "Usage: ice_Client [-s sql]\n");
				exit(1);
			}
		}
		else {
			fprintf(stderr, "Arguments error\n");
			fprintf(stderr, "Usage: ice_Client [-s sql]\n");
			exit(1);
		}
    } catch(const Ice::Exception& ex) {
        cerr << ex << endl;
        status = 1;
    } catch(const char* msg) {
        cerr << msg << endl;
        status = 1;
    }
    if(ic) {
        try {
            ic->destroy();
        } catch (const Ice::Exception& ex) {
            cerr << ex << endl;
            status = 1;
        }
    }
    return status;
}


 

服务器端:

Server.cpp

// **********************************************************************
//
// Copyright (c) 2003-2013 ZeroC, Inc. All rights reserved.
//
// This copy of Ice is licensed to you under the terms described in the
// ICE_LICENSE file included in this distribution.
//
// **********************************************************************

#include <Ice/Ice.h>
#include <Printer.h>
#include <DBoperator.h>

#include <cstdio>
#include <iostream>
#include <cstring>
#include <time.h>
#include <WinSock2.h>
#include <mysql.h>

#pragma comment(lib, "libmysql.lib")

using namespace std;
using namespace Demo;
using namespace dbOperator;

typedef struct synData {
	int count;
	char data[20][20];
}synData;
synData sqlData;

MYSQL *conn = NULL;

char dbName[128], tableName[128], hostName[128], sqlName[128], sqlPwd[128];

/*
 * Printer打印服务
*/
class PrinterI : public Printer {
public:
	virtual void printString(const string &, const Ice::Current&);
};

void PrinterI::printString(const string &s, const Ice::Current&) {
	cout << s << endl;
}
//==================================================================================================

/*
 * Author:X_White
 * 数据库操作服务
*/
class DBOprtrI : public DBOprtr {
public:
	virtual int synDropTab(const Ice::Current&);
	virtual int synAllData(const Ice::Current&);
	virtual int synRowData(const Ice::Current&);
	virtual int synSingleData(const string &, const Ice::Current&);
	virtual int transmitData(const string &, const string&, const Ice::Current&);
};

int DBOprtrI::synDropTab(const Ice::Current&) {
	char sql[128];
	memset(sql, 0, sizeof(sql));

	strcat_s(sql, "DELETE * FROM ");
	strcat_s(sql, tableName);

	return 0;
}

int DBOprtrI::synAllData(const Ice::Current&) {
	char sql[128];
	memset(sql, 0, sizeof(sql));
	strcat_s(sql, "DELETE * FROM ");
	strcat_s(sql, tableName);

	if(mysql_query(conn, sql)) {
		fprintf(stderr, "mysql_query delete failed\n");
		return -1;
	}

	memset(sql, 0, sizeof(sql));
	strcat_s(sql, "UPDATE INTO ");
	strcat_s(sql, tableName);
	strcat_s(sql, " (name, pwd) VALUES (");
	strcat_s(sql, sqlData.data[0]);
	strcat_s(sql, ",");
	strcat_s(sql, sqlData.data[1]);
	strcat_s(sql, ")");

	if(mysql_query(conn, sql)) {
		fprintf(stderr, "mysql_query update failed\n");
		return -1;
	}

	return 0;
}

int DBOprtrI::synRowData(const Ice::Current&) {
	char sql[128];
	memset(sql, 0, sizeof(sql));
	strcat_s(sql, "INSERT INTO ");
	strcat_s(sql, tableName);
	strcat_s(sql, "(name, pwd) VALUES('");
	strcat_s(sql, sqlData.data[0]);
	strcat_s(sql, "','");
	strcat_s(sql, sqlData.data[1]);
	strcat_s(sql, "')");

//	fprintf(stderr, sql);

	if(mysql_query(conn, sql)) {
		fprintf(stderr, "mysql_query insert failed\n");
		return -1;
	}

	return 0;
}

int DBOprtrI::synSingleData(const string &sql, const Ice::Current&) {
	return 0;
}

int DBOprtrI::transmitData(const string &data, const string &index, const Ice::Current&) {

	int num = atoi(index.c_str());
	strcpy_s(sqlData.data[num], data.c_str());

	return 0;
}
//==================================================================================================

void ice_strcpy(char *src, char *des) {
	size_t i;
	size_t len1 = strlen(src);
	size_t len2 = strlen(des);
	for(i = 0; i < len2; i++) {
		src[i] = des[i];
	}
	src[i] = '\0';
}

int writeLog() {
	return 0;
}

/*
 * Author:X_White
 * initConf读取配置文件info.conf 并返回数据库dbName、表名
 *
*/

int initConf(char *dbName, char *tableName, char *hostName, char *sqlName, char *sqlPwd) {
	FILE *conffp;
	errno_t err;
	char buf[1024];
	err = freopen_s(&conffp, "../conf/serverInfo.conf", "r", stdin);
	if(err != 0) {
		writeLog();
		exit(1);
	}
	while(gets_s(buf)) {
		if('#' == buf[0]) continue;
		char n1[128], n2[128], equ[128];
		memset(n1, 0, sizeof(n1));
		memset(n2, 0, sizeof(n2));
		sscanf_s(buf, "%s %s %s", n1, sizeof(n1), equ, sizeof(equ) , n2, sizeof(n2));
//		printf("%s %s\n", tmp, num);
		if(!strcmp(n1, "DataBase")) {
			ice_strcpy(dbName, n2);
		}
		else if(!strcmp(n1, "Table")) {
			ice_strcpy(tableName, n2);
		}
		else if(!strcmp(n1, "HostName")) {
			ice_strcpy(hostName, n2);
		}
		else if(!strcmp(n1, "SqlName")) {
			ice_strcpy(sqlName, n2);
		}
		else if(!strcmp(n1, "SqlPwd")) {
			ice_strcpy(sqlPwd, n2);
		}
	}
	return 0;
}

int sql_init(char *dbName, char *tableName, char *hostName, char *sqlName, char *sqlPwd) {
	conn = mysql_init(NULL);
	if(!conn) {
		fprintf(stderr, "mysql_init failed\n");
		exit(1);
	}
	conn = mysql_real_connect(conn, hostName, sqlName, sqlPwd, dbName, 0, NULL, 0);
	if(!conn) {
		fprintf(stderr, "mysql_real_connect failed\n");
		exit(1);
	}

	return 0;
}

int main(int argc, char* argv[]) {
	int status = 0;
	Ice::CommunicatorPtr ic;

	initConf(dbName, tableName, hostName, sqlName, sqlPwd);
	sql_init(dbName, tableName, hostName, sqlName, sqlPwd);

	try {
		ic = Ice::initialize(argc, argv);
		Ice::ObjectAdapterPtr adapter =
			ic->createObjectAdapterWithEndpoints("SimplePrinterAdapter", "default -h localhost -p 10000");
//		Ice::ObjectAdapterPtr adapter =
//			ic->createObjectAdapterWithEndpoints("DBOperatorAdapter", "default -h localhost -p 10000");
		Ice::ObjectPtr object = new PrinterI;
		Ice::ObjectPtr objectDB = new DBOprtrI;
		adapter->add(object, ic->stringToIdentity("SimplePrinter"));
		adapter->activate();
		adapter->add(objectDB, ic->stringToIdentity("DBOperator"));
		adapter->activate();
		ic->waitForShutdown();
	} catch(const Ice::Exception& e) {
		cerr << e << endl;
		status = 1;
	} catch(const char* msg) {
		cerr << msg << endl;
		status = 1;
	}
	if(ic) {
		try {
			ic->destroy();
		} catch(const Ice::Exception& e) {
			cerr << e << endl;
			status = 1;
		}
	}
	mysql_close(conn);

	return status;
}


 

运行Servre后,再运行Client。发现目标数据库中已经得到了同步数据。

 

目前只是一个Demo,部分函数只是写了个框架,并没有实现,到时候在根据需求进行实现。

 

 

 

 

 

 

 

 

 

 

 

 

 

你可能感兴趣的:(ZeroC—ICE分布式数据同步Demo)