1. 程式人生 > 實用技巧 >go實現聊天系統(2)

go實現聊天系統(2)

1.定義訊息型別

package Common
const (
	LoginMesType   = "LoginMes"
	LoginResType	= "LoginResMes"
)
type Message struct {
	Type string `json:"type"` //訊息型別
	Data string `json:"data"` //訊息內容
}
type LoginMes struct {
	UserId int `json:"userid"`
	UserPwd string `json:"userpwd"`
	UserName string `json:"username"`
}
type LoginResMes struct {
	Code int `json:"code"`
	Error string `json:"error"`
}

2.完成伺服器端程式碼功能

package main
import (
	"fmt"
	"net"
)
func process(conn net.Conn){
	fmt.Println("讀取客戶端傳送的連線");
	defer  conn.Close();//這裡需要延時關閉,如果不過關閉奇怪情況
	buf:=make([]byte,8096);
	for {
		fmt.Println("等待讀取傳送的資料");
		n,err:=conn.Read(buf[0:4]);
		if n != 4 || err != nil {
			fmt.Println("conn is error");
			return;
		}
		fmt.Println("read length buf=",buf[:4]);
	}
}
func main(){
	fmt.Println("伺服器在8889埠監聽....");
	listen,err:= net.Listen("tcp","0.0.0.0:8889");
	if err !=nil {
		fmt.Printf("net.Listen is error");
	}
	for {
		fmt.Println("等待客戶端的連線");
		conn,err := listen.Accept();
		if err != nil {
			fmt.Println("listen accept is err");
		}
		go process(conn);
	}
}

3.完成客戶端程式碼書寫

package main
import "fmt"
var userId int;
var userPwd string;
func main(){
	var key int;
	var loop=true;
	for loop {
		fmt.Println("----------------------歡迎多人聊天系統----------------------");
		fmt.Println("\t\t\t 1:登入聊天室");
		fmt.Println("\t\t\t 2:註冊使用者");
		fmt.Println("\t\t\t 3:退出系統");
		fmt.Println("\t\t\t 請選擇(1-3):");
		fmt.Scanf("%d\n",&key);
		switch key {
			case 1:
				fmt.Println("登入聊天系統頁面");
				loop=false;
			case 2:
				fmt.Println("註冊使用者頁面");
				loop=false;
			case 3:
				fmt.Println("退出系統");
				loop=false;
			default:
				fmt.Println("你的輸入有誤,請重新輸入");
		}
	}
	if key == 1 {
		fmt.Println("請輸入使用者ID:");
		fmt.Scanf("%d\n",&userId);
		fmt.Println("請輸入使用者密碼:");
		fmt.Scanf("%s\n",&userPwd);
		login(userId,userPwd);
	}
}

  

package main

import (
    Common "common"
    "encoding/binary"
    "encoding/json"
    "fmt"
    "net"
)
func login(userId int,userPwd string) (err error) {
    fmt.Printf("登入學生ID為%v 密碼為%v",userId,userPwd);
    //連線遠端伺服器
    conn,err:=net.Dial("tcp","localhost:8889");
    if err != nil {
        fmt.Println("net.Dial is error");
    }
    defer  conn.Close();

    var msg Common.Message;
    //1.設定訊息型別
    msg.Type=Common.LoginMesType;//設定登入結構體型別
    //2.建立訊息結構體
    var logMes Common.LoginMes;
    logMes.UserId=userId;
    logMes.UserName=userPwd;
    data,err:= json.Marshal(logMes);//將訊息內容序列化但是data是切片
    if err != nil {
        fmt.Println("json.Marshal is error");
        return;
    }
    msg.Data=string(data);
    //3.將全部訊息序列化
    data,err = json.Marshal(msg);//這是切片
    if err != nil {
        fmt.Println("json.Marshal is error");
        return;
    }
    //討論如何傳送
    pkgLen:= uint32(len(data));
    var bytes [4]byte;
    binary.BigEndian.PutUint32(bytes[0:4],pkgLen);//這個是重點需要將資料長度轉換為位元組序列
    n,err:=conn.Write(bytes[0:4]);
    if n != 4 || err != nil {
        fmt.Println("send is error");
        return;
    }
    fmt.Println("mess length is success");
    return;
}