在做智能农场项目过程中,有一个问题:这个项目是基于c/s架构,但是有两个服务器,分别是与感知层交互的服务器、与QT客户端交互的服务器,如何做到QT服务器发出反控命令到数据库后能够使底层服务器实时读取命令并执行,想到几个方法:1、QT服务器与硬件服务器进程间通信,但考虑到以后QT服务器可能改为WEB服务器,这时候进程间通信不适用;2、如果采用服务器定时轮询查看,可能会因不及时造成业务上的不便。 不提闲话了,以下为个人利用mysql触发器在C项目中的用法:
create function sock_mysql RETURNS INTEGER SONAME 'libmysqludf2.so' //创建sock_mysql()函数链接libmysqludf2.so 库
delimiter | //修改mysql语句以“|”结尾,触发器使用完后记得改回来,避免影响以后mysql语句的正常使用
create trigger Contrl_Qt after update on control for each row //在每次更新“control”表(每行都适用)之后创建名为Contrl_Qt的触发器
//也可以将“after”改为“before”,意为“之前”
//也可以将“update”改为“insert”等
begin //以下为触发器函数实现代码
declare ab varchar(20); //使用关键字定义ab变量
set ab=sock_mysql(new.Q_value); //set关键字给ab赋值
end| //以“|”结尾,结束mysql语句
这里涉及到mysql的UDF(User defined function):sock_mysql()函数(名字随意)、初始化函数sock_mysql_init()、释放函数sock_mysql_deinit()
以下为供学习代码,作用为:在sock_mysql()函数内建立TCP客户端,连接服务器向服务器发送从数据库读到的数据。
————附上大神“印风”关于UDF讲解的链接:(http://blog.csdn.net/zhaiwx1987/article/details/6902623)
#if defined(_WIN32) || defined(_WIN64) || defined(__WIN32__) || defined(WIN32)
#define DLLEXP __declspec(dllexport)
#else
#define DLLEXP
#endif
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
#include<sys/types.h>
#include<sys/ipc.h>
#include<unistd.h>
#include <my_global.h>
#include <my_sys.h>
#include<mysql.h>
#include<sys/socket.h>
#include<errno.h>
#include<arpa/inet.h>
#define ERR(msg) do{\
fprintf(stderr,"[%s:%d]%s:%s",__FILE__,__LINE__,msg,strerror(errno));\
exit(-1);\
}while(0)
#if 1
/* These must be right or mysqld will not find the symbol! */
DLLEXP
my_bool sock_mysql(UDF_INIT *initid,UDF_ARGS *args,char *is_null,char *error);
DLLEXP
my_bool sock_mysql_init(UDF_INIT *initid,UDF_ARGS *args,char *message);
DLLEXP
void sock_mysql_deinit(UDF_INIT *initid);
#endif
my_bool sock_mysql_init(UDF_INIT *initid,UDF_ARGS *args,char *message)
{
if(args->arg_count!=1)
{
strcpy(message,"Expected exactly 2 arguments");
return 1;
}
if(args->arg_type[0]!=STRING_RESULT)
// if(args->arg_type[0]!=INT_RESULT)
{
strcpy(message,"Expected string type for name parameter");
return 1;
}
// args->arg_type[1]=INT_RESULT;
if((initid->ptr=malloc( args->lengths[0] +1))==NULL)
{
strcpy(message,"Could not allocate memory");
return 1;
}
return 0;
}
void sock_mysql_deinit(UDF_INIT *initid)
{
if (initid->ptr!=NULL)
{ free(initid->ptr);}
}
my_bool sock_mysql(UDF_INIT *initid,UDF_ARGS *args,char *is_null,char *error)
{
struct sockaddr_in myaddr;
char sndbuf[20];
char buff[20];
memcpy(sndbuf,args->args[0],args->lengths[0]);
*(sndbuf+args->lengths[0])='\0';
// float s=args->args[1];
int sockfd = socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
if(sockfd == -1)
ERR("socket");
memset(&myaddr,0,sizeof(myaddr));
myaddr.sin_family = AF_INET;
myaddr.sin_port = htons(8083);
myaddr.sin_addr.s_addr = inet_addr("192.168.197.128");
if(connect(sockfd,(struct sockaddr *)&myaddr,sizeof(myaddr)) == -1)
{
ERR("connect");
}
// sprintf(sndbuf,"%s#%.2f",buff,s);
// printf("%s",sndbuf);
// strcpy(sndbuf,"hello");
send(sockfd,sndbuf,1024,0);
close(sockfd);
return 0;
}
UDF需要生成库并存放于mysql路径下,库名应与触发器中提到的库名一致