Go webrtc实现1v1聊天

offer.go

package main

import (
	"bufio"
	"encoding/base64"
	"encoding/json"
	"fmt"
	"github.com/pion/webrtc/v4"
	"log"
	"os"
	"strconv"
	"time"
)

func main() {
	config := webrtc.Configuration{
		ICEServers: []webrtc.ICEServer{
			{
				URLs: []string{"stun:stun.l.google.com:19302"},
			},
		},
	}
	// 1. create peer connection
	peerConnection, err := webrtc.NewPeerConnection(config)
	if err != nil {
		return
	}
	defer func() {
		if err := peerConnection.Close(); err != nil {
			log.Println(err.Error())
		}
	}()
	// 2. create data channel
	dataChannel, err := peerConnection.CreateDataChannel("foo", nil)
	dataChannel.OnOpen(func() {
		log.Println("data channel has opened")
		i := -1000
		for range time.NewTicker(time.Second * 5).C {
			if err := dataChannel.SendText("offer : hello world " + strconv.Itoa(i)); err != nil {
				log.Println(err.Error())
			}
		}
	})
	dataChannel.OnMessage(func(msg webrtc.DataChannelMessage) {
		fmt.Println(string(msg.Data))
	})
	// 3. create offer
	offer, err := peerConnection.CreateOffer(nil)
	if err != nil {
		return
	}
	// 4. set local description
	err = peerConnection.SetLocalDescription(offer)
	if err != nil {
		return
	}
	// 5. print offer
	println("OFFER:")
	println(encode(&offer))
	// 6. input answer
	println("请输入ANSWER:")
	var answer webrtc.SessionDescription
	answerStr, _ := bufio.NewReader(os.Stdin).ReadString('\n')
	decode(answerStr, &answer)
	// 7. set remote description
	if err := peerConnection.SetRemoteDescription(answer); err != nil {
		panic(err)
	}
	// 主循环,
	select {}
}
func encode(obj *webrtc.SessionDescription) string {
	b, err := json.Marshal(obj)
	if err != nil {
		panic(err)
	}

	return base64.StdEncoding.EncodeToString(b)
}

func decode(in string, obj *webrtc.SessionDescription) {
	b, err := base64.StdEncoding.DecodeString(in)
	if err != nil {
		panic(err)
	}

	if err = json.Unmarshal(b, obj); err != nil {
		panic(err)
	}
}

answer.go

package main

import (
	"bufio"
	"encoding/base64"
	"encoding/json"
	"fmt"
	"github.com/pion/webrtc/v4"
	"log"
	"os"
	"strconv"
	"time"
)

func main() {
	config := webrtc.Configuration{
		ICEServers: []webrtc.ICEServer{
			{
				URLs: []string{"stun:stun.l.google.com:19302"},
			},
		},
	}
	// 1. create peer connection
	peerConnection, err := webrtc.NewPeerConnection(config)
	if err != nil {
		return
	}
	defer func() {
		if err := peerConnection.Close(); err != nil {
			log.Println(err.Error())
		}
	}()
	// 2. on data channel
	peerConnection.OnDataChannel(func(dataChannel *webrtc.DataChannel) {
		dataChannel.OnOpen(func() {
			log.Println("data channel has opened")
			i := -1000
			for range time.NewTicker(time.Second * 5).C {
				if err := dataChannel.SendText("answer : hello world " + strconv.Itoa(i)); err != nil {
					log.Println(err.Error())
				}
			}
		})
		dataChannel.OnMessage(func(msg webrtc.DataChannelMessage) {
			fmt.Println(string(msg.Data))
		})
	})
	// 3. input offer
	println("请输入OFFER:")
	offerStr, _ := bufio.NewReader(os.Stdin).ReadString('\n')
	var offer webrtc.SessionDescription
	decode1(offerStr, &offer)
	// 4. set remote description
	if err := peerConnection.SetRemoteDescription(offer); err != nil {
		panic(err)
	}
	// 5. create answer
	answer, err := peerConnection.CreateAnswer(nil)
	if err != nil {
		panic(err)
	}
	// 6. set local description
	if err := peerConnection.SetLocalDescription(answer); err != nil {
		panic(err)
	}
	// 7. gather complete
	gatherComplete := webrtc.GatheringCompletePromise(peerConnection)
	<-gatherComplete
	// 8. print answer
	fmt.Println("ANSWER:")
	fmt.Println(encode1(peerConnection.LocalDescription()))
	// 主循环
	select {}
}

func encode1(obj *webrtc.SessionDescription) string {
	b, err := json.Marshal(obj)
	if err != nil {
		panic(err)
	}

	return base64.StdEncoding.EncodeToString(b)
}

func decode1(in string, obj *webrtc.SessionDescription) {
	b, err := base64.StdEncoding.DecodeString(in)
	if err != nil {
		panic(err)
	}

	if err = json.Unmarshal(b, obj); err != nil {
		panic(err)
	}
}

使用方式

go run client.go 会打印出OFFER的字符串,复制OFFER字符串到answer的OFFER输入框内,然后复制answer的ANSWER到offer的ANSWER输入框,也就是说offer与answer需要交换


go run answer.go 复制OFFER字符串到answer的OFFER输入框内,然后复制answer的ANSWER到offer的ANSWER输入框,也就是说offer与answer需要交换


posted @   朝阳1  阅读(91)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· 因为Apifox不支持离线,我果断选择了Apipost!
点击右上角即可分享
微信分享提示