go语言:200行代码做udp rtp转发并发分布服务器

12 篇文章 1 订阅

使用go做服务器

最近写服务器使用c++多了以后,java和node逐渐被放到一边,最后又做了一个决定,使用go来做服务器,将会使用200行代码不到来做这个并发和分布式服务器,为什么?

go语言的优势

前面的文章有我的所见:看这个go语言优势和使用结构体与链表

以下内容还没有完全完成,需要继续修改…敬请关注

流程

udpserver就是我们要做的转发服务
httpserver是我们的信令服务

接受链接
接受询问
udpserver
RTP和文字聊天转发
httpserver
返回udpserver的地址和认证code

就这样简单

show me the code

主体代码没有完全完成,但已经成型

package main
import (
	"io"
    "fmt"
    "net"
	"net/http"
    "os"
	"log"
	"container/list"
)


type s_client struct{
    num int
    name string
	*net.UDPAddr
}
 
var g_client = list.New()
//var g_clients map[uint]list //uint 是ssrc,list是请求的链表
var limitChan = make(chan bool, 1000)
// hello world, the web server
func HelloServer(w http.ResponseWriter, req *http.Request) {
	//返回服务器的端口地址,可以有多个服务器来进行负载均衡
    io.WriteString(w, "127.0.0.1:8080")
}
// UDP goroutine concurrency to read UDP maybe not parallelism,maybe in onethread maybe in multi thread,maybe yes,maybe no
func udpProcess(conn *net.UDPConn)  {
    data := make([]byte, 1024)
    n,remoteAddr,err := conn.ReadFromUDP(data)
    if err != nil {
        fmt.Println("Failed To Read UDP Msg, Error: " + err.Error())
    }

    //var flag = 0x80
	if(data[0] == 0x80){//RTP 协议
		if n < 13 {
			fmt.Println("client error")
		}else {
			//转发
			conn.WriteToUDP([]byte("test"), remoteAddr)
		}
        //求取RTP ssrc
	}

	//Call Endc Resp Read
	str :=string(data[0:3])
	if str == "Call" { //单点找人

	}else if str=="Pull" {//拉取流
		fmt.Println("pull")
		//ssrc := 1234
		//l := list.New()
		//l.PushBack(s_client{1,"name",remoteAddr})
        //g_clients[ssrc] = l
		g_client.PushBack(s_client{1,"name",remoteAddr})
	}else if str=="Resp" {//

	}else if str == "Chat" {

	}else if str == "Endc" {

	}else {

	}

    //str := string(data[:n])
    //fmt.Println("Reveive From Client, Data: " + str)
    <- limitChan
}

func udpServer(address string)  {
	fmt.Println("server start at udp 8080")
    udpAddr, err := net.ResolveUDPAddr("udp", address)
    conn, err := net.ListenUDP("udp", udpAddr)
    defer conn.Close()

    if err != nil {
        fmt.Println("Read From Connect Failed, Err :" + err.Error())
        os.Exit(1)
    }

    for {
        limitChan <- true
        go udpProcess(conn)
    }

}

func httpServer(address string) {
	http.HandleFunc("/push", HelloServer)
	fmt.Println("server http start at 8080")
    err := http.ListenAndServe(":8080", nil)
    if err != nil {
        log.Fatal("ListenAndServe: ", err)
    }
}

func main() {

	//g_clients :=make(map[uint]list)
	//client[32]="qianbo"
    address := "0.0.0.0:8080"
	go httpServer(address)
       
    udpServer(address)
}

启动了一个协程来运行httpserver,接受客户端询问,返回udpserver地址,有信令服务器就可以返回多个udpserver中的一个,这样就能打造分布式服务器,udpserver如何转发呢个,客户端知道服务器地址后,使用认证session询问,发包传到服务器一个探测询问包,服务器回传一个包,打通了双方地址,服务器在内网也是可以的,这时候要用stun服务器,这里暂时服务器在外网,使用RTP协议上传数据后,服务器负责转发,客户端存储在链表中,现在代码100行,完成时应该在200行左右,服务器使用协程运行,并发控制在1000,依照服务器能力,可做修改

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

qianbo_insist

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值