314 lines
6.3 KiB
Go
314 lines
6.3 KiB
Go
package lib
|
|
|
|
import (
|
|
"chat/dao"
|
|
"chat/message"
|
|
"chat/process"
|
|
"chat/rdm"
|
|
"chat/user"
|
|
"context"
|
|
"encoding/json"
|
|
"errors"
|
|
"fmt"
|
|
"io/ioutil"
|
|
"net"
|
|
"strconv"
|
|
"time"
|
|
)
|
|
|
|
type Server struct {
|
|
Id int
|
|
Users []user.User
|
|
Messages message.Message
|
|
}
|
|
|
|
const SavePath = "./data.json"
|
|
|
|
var Rchan = make(chan process.Ms, 100000)
|
|
|
|
func NewServer() *Server {
|
|
data, err := ioutil.ReadFile(SavePath)
|
|
if err == nil {
|
|
s := &Server{}
|
|
x := json.Unmarshal(data, s)
|
|
if x != nil {
|
|
return &Server{}
|
|
}
|
|
return s
|
|
}
|
|
return &Server{}
|
|
}
|
|
|
|
func (server *Server) Login(uid int, pw string) (*user.User, error) {
|
|
for _, u := range server.Users {
|
|
if uid == u.Id && pw == u.Password {
|
|
return &u, nil
|
|
}
|
|
}
|
|
u := rdm.GetRdm().HGetAll(context.Background(), user.GetUserKey(uid))
|
|
if u != nil && u.Val()["password"] == pw {
|
|
t := u.Val()
|
|
id, _ := strconv.Atoi(t["id"])
|
|
sex, _ := strconv.Atoi(t["sex"])
|
|
uu := &user.User{
|
|
Id: id,
|
|
Name: t["name"],
|
|
Sex: int8(sex),
|
|
//Password: "",
|
|
}
|
|
return uu, nil
|
|
}
|
|
return nil, errors.New("not found this user")
|
|
}
|
|
|
|
func (server *Server) Store() {
|
|
data, err := json.Marshal(server)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
err = ioutil.WriteFile(SavePath, data, 0755)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
}
|
|
|
|
func (server *Server) AddUser(name, pw string, sex int8) error {
|
|
server.Id++
|
|
u := user.User{
|
|
Id: server.Id, Name: name, Sex: sex, Password: pw,
|
|
}
|
|
server.Users = append(server.Users, u)
|
|
err := dao.AddUser(u)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (server *Server) Process(conn net.Conn) {
|
|
m := make([]byte, 0)
|
|
read, err := conn.Read(m)
|
|
if err != nil {
|
|
return
|
|
}
|
|
fmt.Println(read)
|
|
}
|
|
|
|
func notice(message2 message.Message) {
|
|
for _, userProcess := range process.GetOnlineUsers() {
|
|
err := process.WriteConn(userProcess.Conn, message2)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func (server *Server) do(s *message.LoginS, conn net.Conn) (string, error) {
|
|
login, err := server.Login(s.Uid, s.Pw)
|
|
re := message.Message{
|
|
Type: "login_response",
|
|
Data: nil,
|
|
}
|
|
|
|
r := message.Correspond{
|
|
Code: 0,
|
|
Msg: "login fail",
|
|
Error: "pw fail or login not exist ",
|
|
}
|
|
if err == nil {
|
|
r.Code = 1
|
|
r.Msg = login.Name
|
|
r.Error = ""
|
|
r.User = *login
|
|
notice(message.Message{
|
|
Type: "notice",
|
|
Code: 0,
|
|
Msg: fmt.Sprintf("%s已上线", login.Name),
|
|
Data: nil,
|
|
})
|
|
process.Push(&process.UserProcess{
|
|
Uid: login.Id,
|
|
Conn: conn,
|
|
})
|
|
} else {
|
|
r.Error += err.Error()
|
|
}
|
|
re.Data = r
|
|
|
|
err = process.WriteConn(conn, re)
|
|
return "login_send", err
|
|
}
|
|
|
|
func (s *Server) processConn() {
|
|
defer func() {
|
|
if r := recover(); r != nil {
|
|
fmt.Println(r)
|
|
}
|
|
}()
|
|
for {
|
|
select {
|
|
case c := <-Rchan:
|
|
switch c.Msg.Type {
|
|
case "login_send":
|
|
l := c.Msg.Data.(*message.LoginS)
|
|
_, err := s.do(l, c.Conn)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
}
|
|
case "add_user":
|
|
u := c.Msg.Data.(*user.User)
|
|
err := s.AddUser(u.Name, u.Password, u.Sex)
|
|
r := message.Message{
|
|
Type: "add_user_response",
|
|
Code: 1,
|
|
Msg: "",
|
|
Data: nil,
|
|
}
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
r.Msg = err.Error()
|
|
r.Code = 0
|
|
}
|
|
err = process.WriteConn(c.Conn, r)
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
}
|
|
case "user_message":
|
|
data := c.Msg.Data.(*message.UserMessage)
|
|
now := time.Now().Format("2006-01-02 15:04:05")
|
|
if data.TotUid > 0 {
|
|
to := process.Get(data.TotUid)
|
|
if to == nil {
|
|
to = process.Get(data.FromUid)
|
|
if to == nil {
|
|
break
|
|
}
|
|
toU := dao.UserInfo(data.TotUid)
|
|
err := process.WriteConn(to.Conn, message.Message{
|
|
Type: "notice",
|
|
Code: 0,
|
|
Msg: "用户" + toU.Name + "已下线",
|
|
Data: nil,
|
|
})
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
}
|
|
break
|
|
}
|
|
err := process.WriteConn(to.Conn, message.Message{
|
|
Type: "user_message",
|
|
Code: 0,
|
|
Msg: "",
|
|
Data: message.UserMessage{
|
|
FromUid: data.FromUid,
|
|
FromUserName: data.FromUserName,
|
|
TotUid: data.TotUid,
|
|
Msg: data.Msg,
|
|
Datetime: now,
|
|
},
|
|
})
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
}
|
|
|
|
} else {
|
|
fmt.Println(data.FromUserName, ":", data.Msg)
|
|
for _, userProcess := range process.GetOnlineUsers() {
|
|
err := process.WriteConn(userProcess.Conn, message.Message{
|
|
Type: "all_users",
|
|
Code: 0,
|
|
Msg: "",
|
|
Data: message.AllUser{
|
|
FromUid: data.FromUid,
|
|
FromUserName: data.FromUserName,
|
|
Msg: data.Msg,
|
|
DateTime: now,
|
|
},
|
|
})
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
}
|
|
}
|
|
}
|
|
case "online_users":
|
|
all := process.GetOnlineUsers()
|
|
arr := make([]message.UserPre, 0)
|
|
for _, userProcess := range all {
|
|
v := rdm.GetRdm().HGet(context.Background(), user.GetUserKey(userProcess.Uid), "name").Val()
|
|
arr = append(arr, message.UserPre{
|
|
Id: userProcess.Uid,
|
|
Name: v,
|
|
})
|
|
}
|
|
err := process.WriteConn(c.Conn, message.Message{
|
|
Type: "online_users",
|
|
Code: 1,
|
|
Msg: "",
|
|
Data: message.UsersPres{Data: arr},
|
|
})
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
}
|
|
case "offline":
|
|
id := process.Disconnect(c.Conn)
|
|
u := dao.UserInfo(id)
|
|
for _, userProcess := range process.GetOnlineUsers() {
|
|
err := process.WriteConn(userProcess.Conn, message.Message{
|
|
Type: "notice",
|
|
Code: 0,
|
|
Msg: "用户" + u.Name + "已下线",
|
|
Data: nil,
|
|
})
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
func (server *Server) read(conn net.Conn) {
|
|
defer func(conn net.Conn) {
|
|
err := conn.Close()
|
|
if err != nil {
|
|
id := process.Disconnect(conn)
|
|
u := dao.UserInfo(id)
|
|
for _, userProcess := range process.GetOnlineUsers() {
|
|
err := process.WriteConn(userProcess.Conn, message.Message{
|
|
Type: "notice",
|
|
Code: 0,
|
|
Msg: "用户" + u.Name + "已掉线",
|
|
Data: nil,
|
|
})
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
}
|
|
}
|
|
fmt.Println(err, "ssssssssssssssss")
|
|
}
|
|
}(conn)
|
|
|
|
process.Read(conn, Rchan)
|
|
|
|
}
|
|
|
|
func (server *Server) Start() {
|
|
listen, err := net.Listen("tcp", "0.0.0.0:8989")
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
return
|
|
}
|
|
go server.processConn()
|
|
for {
|
|
conn, err := listen.Accept()
|
|
if err != nil {
|
|
fmt.Println(err)
|
|
continue
|
|
}
|
|
go server.read(conn)
|
|
}
|
|
}
|