date | status | title |
---|---|---|
2017-10-14 21:42 |
public |
会员招新服务端说明 |
func main() {
mylog.StartLog()//开始记录日志
*************
向日志打印启动信息
*************
appconf.Read_conf()//读取配置文件
*************
打印信息
*************
//数据库初始化
associator_pkg.Init_sqllite_databse()
W.Add(1)//添加一个信号量。
//Http服务初始化
go myhttp.Http_server_init()
//Udp心跳广播服务初始化
go sent_udp_heartbeak.Boardcast_udp_heartbeak_to_all_netcard()
//for {
//}
W.Wait()//等待信号量,这里主要用于阻塞main函数,防止程序关闭,和while(1);作用类似,但是while(1);消耗cpu。
associator_pkg.Db.Close()
}
type ServerConfig struct {
SqlDb string `goconf:"database:SqlDb"` //数据库路径
SqlAssociatorTable string `goconf:"database:SqlAssociatorTable"` //数据库的会员表的名字
SqlAssociatorNumberTable string `goconf:"database:SqlAssociatorNumberTable"` //数据库的会员号表的名字
SqlAdministratorTable string `goconf:"database:SqlAdministratorTable"` //数据库的管理员表的名字
HttpAddr string `goconf:"http:HttpAddrAndPort"` //http的地址和端口
HttpsEnable string `goconf:"http:HttpsEnable"` //使能https
HttpsCertFile string `goconf:"http:HttpsCertFile"` //https的Certfile路径
HttpsKeyFile string `goconf:"http:HttpsKeyFile"` //https的keyfile的路径
HttpPort int `goconf:"http:HttpOnlyPort"` //心跳包里包含的http的端口,必须跟上面定义的一样
HttpReadTimeout time.Duration `goconf:"http:HttpReadTimeout"` //http读超时
HttpWriteTimeout time.Duration `goconf:"http:HttpWriteTimeout"` //http写超时
HttpMaxHeaderBytes int `goconf:"http:HttpMaxHeaderBytes"` //http读取最大字节
UdpServerPort int `goconf:"udp:UdpServerPort"` //udp服务端端口
UdpClientPort int `goconf:"udp:UdpClientPort"` //udp客户端端口
UdpHeartbeakTime time.Duration `goconf:"udp:UdpHeartbeakTime"` //udp心跳包刷新时间
}
var Tf *ServerConfig //定义一个全局的配置结构体
func Read_conf() { //读取并解析配置文件函数
conf := goconf.New()
Tf = &ServerConfig{}
if err := conf.Parse("../conf/app.conf"); err != nil {
************
省略部分代码
************
if err := conf.Unmarshal(Tf); err != nil {
************
省略部分代码
************
**************
对读取到的配置信息进行合法性过滤和修正
**************
}
type Associator_s struct {//定义一个会员数据的结构体
***********************
省略会员数据的结构体
***********************
}
var Db *sql.DB //声明一个全局的数据库连接句柄,用于初始化数据库后操作数据库不需要再次初始化数据库。
var Sqlite_operation_lock *sync.Mutex//定义一个sqlite3的全局锁,用于强制数据库操作串行执行,防止出现冲突。这里以后可以优化成并行操作。加快效率。
func Init_sqllite_databse() {
var err error
Db, err = sql.Open("sqlite3", appconf.Tf.SqlDb)//打开数据库文件
**************
省略部分代码
**************
_, err = Db.Query("SELECT * FROM " + appconf.Tf.SqlAssociatorTable)//检查数据库是否合法
**************
省略部分代码
**************
fmt.Println("sqlite3数据库初始化成功!!(addr:" + appconf.Tf.SqlDb + ")")
Sqlite_operation_lock = new(sync.Mutex)//初始化数据库串行锁
}
func create_associator_table() {
var create_associator_table_sql_text string = `
************
创建会员表的sql语句
***********
var create_number_table_sql_text string = `
************
创建缓存会员号表的sql语句
***********
var create_administrator_table_sql_text string = `
************
创建管理员表的sql语句
***********
var init_number_table_sql_text string = `
************
创建缓存会员号表表的sql语句
***********
************
省略部分代码
***********
_, err = Db.Exec(create_associator_table_sql_text) //这里使用Exec函数,因为这里是执行,经测试Query函数执行失败
************
初始化失败就报错并关闭数据库连接
***********
_, err = Db.Exec(create_number_table_sql_text) //这里使用Exec函数,因为这里是执行,经测试Query函数执行失败
************
初始化失败就报错并关闭数据库连接
***********
_, err = Db.Exec(create_administrator_table_sql_text) //这里使用Exec函数,因为这里是执行,经测试Query函数执行失败
************
初始化失败就报错并关闭数据库连接
***********
_, err = Db.Exec(init_number_table_sql_text) //这里使用Exec函数,因为这里是执行,经测试Query函数执行失败
************
初始化失败就报错并关闭数据库连接
***********
fmt.Println("尝试修复sqlite3数据库成功!!")
}
func Cancel_associator_number(associator Associator_s) (string, error)//取消会员号的入口函数(注意入口函数都是全局的),判断是否要执行取消会员号操作
func database_cancel_associator_number(associator Associator_s, associator_number string) (string, error)//执行取消会员号操作
func Change_associator_card_id(associator Associator_s) error//修改会员卡号的入口函数(注意入口函数都是全局的),判断是否要执行修改会员卡号操作
func check_this_card_id_is_exsite(associator Associator_s)//检查会员卡是否已存在
func database_change_associator_card_id(associator Associator_s)//执行修改会员卡号操作
func Change_associator_receipt_status(associator Associator_s) error//修改会员收据打印状态的入口函数(注意入口函数都是全局的),判断是否要执行修改会员收据打印状态操作
func database_change_associator_receipt_status(associator Associator_s) error//修改会员收据打印状态的执行函数
func Check_associator_exist_card_id(associator Associator_s) (bool, error)执行检查会员是否存在会员卡号操作
Check_associator_receipt_adminstrator(associator Associator_s) (string, error)//查询打印这个收据管理员信息
Check_associator_receipt_status(associator Associator_s) (string, error)//检查会员收据打印状态,用于会返回会员的收据打印状态
func Delete_associator(associator Associator_s) (string, error)//删除会员的入口函数(注意入口函数都是全局的),判断是否要执行删除会员操作
func delete_associator_when_it_exist(associator Associator_s) (string, error)//执行删除会员操作
func Get_associator_list_by_receipt_status(receipt_Print_Status string) ([]interface{}, error//根据会员收据打印收据状态获取会员列表
func Get_associator_number(associator Associator_s) (string, error)//申请会员号的入口函数(注意入口函数都是全局的),判断如何进行会员号申请
func database_get_associator_number(associator Associator_s) (string, error)//当这个会员还没有会员号,这个函数会被Get_associator_number这个函数所调用。进行会员号申请操作。
func database_get_new_associator_number(st *sql.Tx) (string, error) //这个函数会被database_get_associator_number函数调用,进行从会员号缓存表里获取一个合法可用的会员号。
func database_get_new_associator_number_when_had_canceled(st *sql.Tx, stmt *sql.Stmt, query *sql.Rows) (string, error)//当缓存会员号表里有冗余的会员号这个函数会被database_get_new_associator_number函数调用并返回一个可用的会员号。
func database_get_new_associator_number_when_hadnt_canceled(st *sql.Tx, stmt *sql.Stmt, query *sql.Rows) (string, error)//当缓存会员号表里没有冗余的会员号这个函数会被database_get_new_associator_number函数调用并返回一个可用的会员号。
func Login_administrator(name string, passwd string) (bool, error) //检查收据管理员是否合法,合法的话第一个返回值会是true,否则false。第二个返回值是报错信息
func Register_associator(associator Associator_s) error//会员注册的入口函数(注意入口函数都是全局的),判断是否进行会员注册。
func database_register_associator(associator Associator_s) error //执行会员注册
func Http_server_init()//初始化http,并且把MyHandle结构体绑定为请求回调接口。
func (*MyHandle) ServeHTTP(w http.ResponseWriter, r *http.Request)//当http数据请求来临时会被调用,w是你写数据的句柄,r是读请求数据的句柄。
func httpfun_cancel_associator_number(w http.ResponseWriter, r *http.Request)
func httpfun_change_associator_card_id(w http.ResponseWriter, r *http.Request)
func httpfun_change_associator_receipt_status(w http.ResponseWriter, r *http.Request)
func httpfun_check_associator_exist_card_number(w http.ResponseWriter, r *http.Request)
func httpfun_check_associator_receipt_adminstrator(w http.ResponseWriter, r *http.Request)
func httpfun_check_associator_receipt_status(w http.ResponseWriter, r *http.Request)
func httpfun_delete_associator(w http.ResponseWriter, r *http.Request)
func httpfun_get_associator_list(w http.ResponseWriter, r *http.Request)
func httpfun_get_associator_number(w http.ResponseWriter, r *http.Request)
func httpfun_login_administrator(w http.ResponseWriter, r *http.Request)
func httpfun_login_administrator(w http.ResponseWriter, r *http.Request)
func httpfun_register_associator(w http.ResponseWriter, r *http.Request)
func StartLog()
func ErrorLog(text string)
func Boardcast_udp_heartbeak_to_all_netcard()
func sent_udp_heartbeak_to_all_netcard()
func sent_udp_heartbeak(ip string)
func sent_udp_heartbeak(ip string)
func sent_udp_boardcast_page(sent_addr net.UDPAddr, page []byte)
var Soft_version string = "1.1.0"
1.0 服务端使用udp广播的方式来发送心跳包,心跳包里包含了服务端的ip,mac,版本等信息。封装心跳包的代码位于服务端源码的(src/dianxie/sent_udp_heartbeak/sent_udp_boardcast.go的func sent_udp_heartbeak(ip string)函数,参数ip是要发送心跳包的网卡的ip)
var heartbeak_json_text []byte
heartbeak_table := make(map[string]interface{})
heartbeak_table["Soft_version"] = soft_version.Soft_version
heartbeak_table["Ip"] = ip
heartbeak_table["HttpSEnable"] = appconf.Tf.HttpsEnable
heartbeak_table["HttpServerPort"] = appconf.Tf.HttpPort
heartbeak_json := make(map[string]interface{})
heartbeak_json["Udp_Heartbeak"] = heartbeak_table
heartbeak_json_text, _ = json.Marshal(heartbeak_json)
var sent_addr net.UDPAddr
sent_addr.IP = net.ParseIP(ip)
sent_addr.Port = appconf.Tf.UdpServerPort
sent_udp_boardcast_page(sent_addr, heartbeak_json_text)
//fmt.Println(ip + " " + string(heartbeak_json_text))
}
```
### 心跳包例子:
```
{"Udp_Heartbeak":{"HttpSEnable":"true","HttpServerPort":8686,"Ip":"192.168.1.182","Soft_version":"1.1.0"}}
{"Register_Associator":{"Name":"会员名字","Class":"班级","Sex":"man或者girl","Phone_Number":"手机号码","QQ_Number":"QQ号码","Wechat_Number":"微信号码",,"Register_Time":"注册时间","Register_MechineTime":"注册时间戳","Register_Mac":"注册的机器的mac地址"}}
{"Get_Associator_List":{"Receipt_Print_Status":"no_proceed"}}
{"Get_Associator_Number":{"Name":"姓名","Class":"班级","Sex":"性别","Phone_Number":"手机号码"}}
{"Change_Associator_Receipt_Status":{"Name":"姓名","Class":"班级","Sex":"性别","Phone_Number":"手机号码","Receipt_Print_Status":"no_proceed","Print_Time":"打印现行时间","Print_MechineTime":"打印现行时间戳","Print_Mac":"本地mac地址","Print_Manager":"管理员名字"}}
{"Chang_Associator_Card_Number":{"Name":"姓名","Class":"班级","Sex":"性别","Phone_Number":"手机号码","Card_Number":"会员卡号"}}
{"Cancel_Associator_Number":{"Name":"姓名","Class":"班级","Sex":"性别","Phone_Number":"手机号码","Number":"会员号码"}}
{"Check_Associator_Exist_Card_Number":{"Name":"姓名","Class":"班级","Sex":"性别","Phone_Number":"手机号码"}}
{"Login_Administrator":{"Name":"管理员账号","Passwd":"管理员密码"}}
{"Check_Associator_Receipt_Status":{"Name":"姓名","Class":"班级","Sex":"性别","Phone_Number":"手机号码"}}
{"Check_Associator_Receipt_Adminstartor":{"Name":"姓名","Class":"班级","Sex":"性别","Phone_Number":"手机号码"}}
{"Delete_Associator":{"Name":"姓名","Class":"班级","Sex":"性别","Phone_Number":"手机号码"}}