diff --git a/package-lock.json b/package-lock.json index e98a61d..ab09e46 100644 --- a/package-lock.json +++ b/package-lock.json @@ -14,6 +14,7 @@ "@testing-library/jest-dom": "^5.11.9", "@testing-library/react": "^13.3.0", "@testing-library/user-event": "^12.6.3", + "@types/ip": "^1.1.3", "@types/jest": "^26.0.20", "@types/node": "^12.19.15", "@types/react": "^18.0.17", @@ -22,6 +23,7 @@ "@types/react-router-dom": "^5.1.7", "history": "^4.9.0", "ionicons": "^7.0.0", + "ip": "^2.0.1", "os": "^0.1.2", "os-browserify": "^0.3.0", "peerjs": "^1.5.4", @@ -47,6 +49,7 @@ "workbox-streams": "^5.1.4" }, "devDependencies": { + "@types/uuid": "^10.0.0", "@typescript-eslint/eslint-plugin": "^5.59.2", "@typescript-eslint/parser": "^5.59.2", "eslint": "^8.35.0", @@ -3767,6 +3770,15 @@ "@types/node": "*" } }, + "node_modules/@types/ip": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/@types/ip/-/ip-1.1.3.tgz", + "integrity": "sha512-64waoJgkXFTYnCYDUWgSATJ/dXEBanVkaP5d4Sbk7P6U7cTTMhxVyROTckc6JKdwCrgnAjZMn0k3177aQxtDEA==", + "license": "MIT", + "dependencies": { + "@types/node": "*" + } + }, "node_modules/@types/istanbul-lib-coverage": { "version": "2.0.6", "resolved": "https://registry.npmjs.org/@types/istanbul-lib-coverage/-/istanbul-lib-coverage-2.0.6.tgz", @@ -3999,6 +4011,13 @@ "resolved": "https://registry.npmjs.org/@types/trusted-types/-/trusted-types-2.0.7.tgz", "integrity": "sha512-ScaPdn1dQczgbl0QFTeTOmVHFULt394XJgOQNoyVhZ6r2vLnMLJfBPd53SB52T/3G36VI1/g2MZaX0cwDuXsfw==" }, + "node_modules/@types/uuid": { + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/@types/uuid/-/uuid-10.0.0.tgz", + "integrity": "sha512-7gqG38EyHgyP1S+7+xomFtL+ZNHcKv6DwNaCZmJmo1vgMugyF3TCnXVg4t1uk89mLNwnLtnY3TpOpCOyp1/xHQ==", + "dev": true, + "license": "MIT" + }, "node_modules/@types/ws": { "version": "8.5.12", "resolved": "https://registry.npmjs.org/@types/ws/-/ws-8.5.12.tgz", @@ -8919,6 +8938,12 @@ "@stencil/core": "^4.0.3" } }, + "node_modules/ip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/ip/-/ip-2.0.1.tgz", + "integrity": "sha512-lJUL9imLTNi1ZfXT+DU6rBBdbiKGBuay9B6xGSPVjUeQwaH1RIGqef8RZkUtHioLmSNpPR5M4HVKJGm1j8FWVQ==", + "license": "MIT" + }, "node_modules/ipaddr.js": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-2.2.0.tgz", @@ -11467,7 +11492,8 @@ "node_modules/os": { "version": "0.1.2", "resolved": "https://registry.npmjs.org/os/-/os-0.1.2.tgz", - "integrity": "sha512-ZoXJkvAnljwvc56MbvhtKVWmSkzV712k42Is2mA0+0KTSRakq5XXuXpjZjgAt9ctzl51ojhQWakQQpmOvXWfjQ==" + "integrity": "sha512-ZoXJkvAnljwvc56MbvhtKVWmSkzV712k42Is2mA0+0KTSRakq5XXuXpjZjgAt9ctzl51ojhQWakQQpmOvXWfjQ==", + "license": "MIT" }, "node_modules/os-browserify": { "version": "0.3.0", diff --git a/package.json b/package.json index 786f45d..9c55f95 100644 --- a/package.json +++ b/package.json @@ -9,6 +9,7 @@ "@testing-library/jest-dom": "^5.11.9", "@testing-library/react": "^13.3.0", "@testing-library/user-event": "^12.6.3", + "@types/ip": "^1.1.3", "@types/jest": "^26.0.20", "@types/node": "^12.19.15", "@types/react": "^18.0.17", @@ -17,6 +18,7 @@ "@types/react-router-dom": "^5.1.7", "history": "^4.9.0", "ionicons": "^7.0.0", + "ip": "^2.0.1", "os": "^0.1.2", "os-browserify": "^0.3.0", "peerjs": "^1.5.4", @@ -42,6 +44,7 @@ "workbox-streams": "^5.1.4" }, "devDependencies": { + "@types/uuid": "^10.0.0", "@typescript-eslint/eslint-plugin": "^5.59.2", "@typescript-eslint/parser": "^5.59.2", "eslint": "^8.35.0", diff --git a/src/components/ExploreContainer.tsx b/src/components/ExploreContainer.tsx index 65623a1..68d8d60 100644 --- a/src/components/ExploreContainer.tsx +++ b/src/components/ExploreContainer.tsx @@ -1,19 +1,13 @@ -/** Гигачады - * Люднев Виталий -Баранова Софья -Белков Семен -Корнеев Владимир -Иноземцев Василий -Болганюк Константин - */ +"use strict"; import React, { useState, useEffect, useCallback } from 'react'; import './ExploreContainer.css'; import InputContainer from './Input'; import { IonButton, IonContent, IonFooter, IonToolbar, IonText, IonModal, IonIcon, IonLoading } from '@ionic/react'; -import { call as callIcon, close as hangUpIcon } from 'ionicons/icons'; +import { call as callIcon, close as hangUpIcon, shirt } from 'ionicons/icons'; import Peer, { MediaConnection } from 'peerjs'; +import * as os from 'os'; const ExploreContainer: React.FC = () => { const [callString, setCallString] = useState(""); @@ -29,9 +23,30 @@ const ExploreContainer: React.FC = () => { const [currentCallId, setCurrentCallId] = useState(null); const [showCopyNotification, setShowCopyNotification] = useState(false); + + + function getLocalIPAddress() { + const networkInterfaces = os.networkInterfaces(); + for (const interfaceName of Object.keys(networkInterfaces)) { + const networkInterface = networkInterfaces[interfaceName]; + if (networkInterface) { + for (const net of networkInterface) { + if (net.family === 'IPv4' && !net.internal) { + console.log(`Your local IP Address is: ${net.address}`); + return net.address; + } + } + } + } + return ''; + } + + getLocalIPAddress(); + useEffect(() => { const initializePeer = () => { - const newPeer = new Peer({ debug: 3 }); + const newPeer = new Peer('',{ debug: 3 }); + // const newPeer = new Peer(,{ debug: 3 }); setPeer(newPeer); newPeer.on('open', (id) => { diff --git a/src/server/websocket-server.js b/src/server/websocket-server.js deleted file mode 100644 index 6e30866..0000000 --- a/src/server/websocket-server.js +++ /dev/null @@ -1,39 +0,0 @@ -// Установите Node.js и ws с помощью команды: npm install ws -const WebSocket = require('ws'); - -const server = new WebSocket.Server({ port: 8080 }); -const clients = {}; - -server.on('connection', (socket) => { - socket.on('message', (message) => { - const data = JSON.parse(message); - switch (data.type) { - case 'register': - clients[data.name] = socket; - console.log(`Клиент ${data.name} подключен`); - break; - case 'offer': - case 'answer': - case 'ice-candidate': - const targetSocket = clients[data.target]; - if (targetSocket) { - targetSocket.send(JSON.stringify(data)); - } else { - console.log(`Целевой клиент ${data.target} не найден`); - } - break; - } - }); - - socket.on('close', () => { - for (let name in clients) { - if (clients[name] === socket) { - console.log(`Клиент ${name} отключен`); - delete clients[name]; - break; - } - } - }); -}); - -console.log('WebSocket сервер запущен на ws://192.168.0.160:8080'); diff --git a/src/service-worker.ts b/src/service-worker.ts index 652a8a4..1f0b1c0 100644 --- a/src/service-worker.ts +++ b/src/service-worker.ts @@ -7,6 +7,14 @@ // code you'd like. // You can also remove this file if you'd prefer not to use a // service worker, and the Workbox build step will be skipped. +/** Гигачады + * Люднев Виталий +Баранова Софья +Белков Семен +Корнеев Владимир +Иноземцев Василий +Болганюк Константин + */ import { clientsClaim } from 'workbox-core'; import { ExpirationPlugin } from 'workbox-expiration'; diff --git a/turn/Dockerfile b/turn/Dockerfile new file mode 100644 index 0000000..04e389b --- /dev/null +++ b/turn/Dockerfile @@ -0,0 +1,9 @@ +FROM golang:1.22.5-alpine3.20 +LABEL author="moxitech" +WORKDIR /var/moxitech_goturn +COPY app /var/moxitech_goturn + +RUN go get ./...; +RUN go build -o main cmd/main.go +EXPOSE 3434 +CMD "./main" \ No newline at end of file diff --git a/turn/app/cmd/main.go b/turn/app/cmd/main.go new file mode 100644 index 0000000..86c941a --- /dev/null +++ b/turn/app/cmd/main.go @@ -0,0 +1,71 @@ +package main + +import ( + "flag" + "log" + "net" + "os" + "os/signal" + "regexp" + "strconv" + "syscall" + + "github.com/pion/turn/v2" +) + +func main() { + publicIP := flag.String("public-ip", "127.0.0.1", "") //"154.194.52.123" + port := flag.Int("port", 8081, "") + users := flag.String("users", "moxitech=moxitech", "") // user=pass,user=pass + realm := flag.String("realm", "callcoocall", "") + flag.Parse() + if len(*publicIP) == 0 { + log.Fatalf("public-ip is required") + } + if len(*users) == 0 { + log.Fatalf("'users' is required") + } + + udpListener, err := net.ListenPacket("udp4", "0.0.0.0:"+strconv.Itoa(*port)) + if err != nil { + log.Panicf("Ошибка создания TURN сервера: %s", err) + } + + usersMap := map[string][]byte{} + for _, kv := range regexp.MustCompile(`(\w+)=(\w+)`).FindAllStringSubmatch(*users, -1) { + usersMap[kv[1]] = turn.GenerateAuthKey(kv[1], *realm, kv[2]) + } + + s, err := turn.NewServer(turn.ServerConfig{ + Realm: *realm, + AuthHandler: func(username string, realm string, srcAddr net.Addr) ([]byte, bool) { + if key, ok := usersMap[username]; ok { + return key, true + } + return nil, false + }, + + PacketConnConfigs: []turn.PacketConnConfig{ + { + PacketConn: udpListener, + RelayAddressGenerator: &turn.RelayAddressGeneratorPortRange{ + RelayAddress: net.ParseIP(*publicIP), + Address: "0.0.0.0", + MinPort: 50000, + MaxPort: 55000, + }, + }, + }, + }) + if err != nil { + log.Panic(err) + } + + sigs := make(chan os.Signal, 1) + signal.Notify(sigs, syscall.SIGINT, syscall.SIGTERM) + <-sigs + + if err = s.Close(); err != nil { + log.Panic(err) + } +} diff --git a/turn/app/go.mod b/turn/app/go.mod new file mode 100644 index 0000000..acccc07 --- /dev/null +++ b/turn/app/go.mod @@ -0,0 +1,14 @@ +module moxitech/turn + +go 1.22.5 + +require ( + github.com/pion/dtls/v2 v2.2.7 // indirect + github.com/pion/logging v0.2.2 // indirect + github.com/pion/randutil v0.1.0 // indirect + github.com/pion/stun v0.6.1 // indirect + github.com/pion/transport/v2 v2.2.1 // indirect + github.com/pion/turn/v2 v2.1.6 // indirect + golang.org/x/crypto v0.8.0 // indirect + golang.org/x/sys v0.9.0 // indirect +) diff --git a/turn/app/go.sum b/turn/app/go.sum new file mode 100644 index 0000000..8da7bf0 --- /dev/null +++ b/turn/app/go.sum @@ -0,0 +1,63 @@ +github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/pion/dtls/v2 v2.2.7 h1:cSUBsETxepsCSFSxC3mc/aDo14qQLMSL+O6IjG28yV8= +github.com/pion/dtls/v2 v2.2.7/go.mod h1:8WiMkebSHFD0T+dIU+UeBaoV7kDhOW5oDCzZ7WZ/F9s= +github.com/pion/logging v0.2.2 h1:M9+AIj/+pxNsDfAT64+MAVgJO0rsyLnoJKCqf//DoeY= +github.com/pion/logging v0.2.2/go.mod h1:k0/tDVsRCX2Mb2ZEmTqNa7CWsQPc+YYCB7Q+5pahoms= +github.com/pion/randutil v0.1.0 h1:CFG1UdESneORglEsnimhUjf33Rwjubwj6xfiOXBa3mA= +github.com/pion/randutil v0.1.0/go.mod h1:XcJrSMMbbMRhASFVOlj/5hQial/Y8oH/HVo7TBZq+j8= +github.com/pion/stun v0.6.1 h1:8lp6YejULeHBF8NmV8e2787BogQhduZugh5PdhDyyN4= +github.com/pion/stun v0.6.1/go.mod h1:/hO7APkX4hZKu/D0f2lHzNyvdkTGtIy3NDmLR7kSz/8= +github.com/pion/transport/v2 v2.2.1 h1:7qYnCBlpgSJNYMbLCKuSY9KbQdBFoETvPNETv0y4N7c= +github.com/pion/transport/v2 v2.2.1/go.mod h1:cXXWavvCnFF6McHTft3DWS9iic2Mftcz1Aq29pGcU5g= +github.com/pion/turn/v2 v2.1.6 h1:Xr2niVsiPTB0FPtt+yAWKFUkU1eotQbGgpTIld4x1Gc= +github.com/pion/turn/v2 v2.1.6/go.mod h1:huEpByKKHix2/b9kmTAM3YoX6MKP+/D//0ClgUYR2fY= +github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= +github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= +github.com/stretchr/objx v0.4.0/go.mod h1:YvHI0jy2hoMjB+UWwv71VJQ9isScKT/TqJzVSSt89Yw= +github.com/stretchr/objx v0.5.0/go.mod h1:Yh+to48EsGEfYuaHDzXPcE3xhTkx73EhmCGUpEOglKo= +github.com/stretchr/testify v1.7.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg= +github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= +github.com/stretchr/testify v1.8.3/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXlSw2iwfAo= +github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= +golang.org/x/crypto v0.8.0 h1:pd9TJtTueMTVQXzk8E2XESSMQDj/U7OUu0PqJqPXQjQ= +golang.org/x/crypto v0.8.0/go.mod h1:mRqEX+O9/h5TFCrQhkgjo2yKi0yYA+9ecGkdQoHrywE= +golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4= +golang.org/x/mod v0.8.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= +golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= +golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= +golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs= +golang.org/x/net v0.9.0/go.mod h1:d48xBJpPfHeWQsugry2m+kC02ZBRGRgulfHnEXEuWns= +golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.7.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.9.0 h1:KS/R3tvhPqvJvwcKfnBHJwwthS11LRhmM5D59eEXa0s= +golang.org/x/sys v0.9.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= +golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= +golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k= +golang.org/x/term v0.7.0/go.mod h1:P32HKFT3hSsZrRxla30E9HqToFYAQPCMs/zFMBUFqPY= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= +golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= +golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= +golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8= +golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8= +golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= +golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc= +golang.org/x/tools v0.6.0/go.mod h1:Xwgl3UAJ/d3gWutnCtw505GrjyAbvKui8lOU390QaIU= +golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0= +gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= +gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= +gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/turn/docker-compose.yml b/turn/docker-compose.yml new file mode 100644 index 0000000..de1d40d --- /dev/null +++ b/turn/docker-compose.yml @@ -0,0 +1,26 @@ +version: '3.9' + +networks: + moxitech-network: + driver: bridge + + +services: + + + turn_server: + container_name: turn + build: + context: . + dockerfile: Dockerfile + networks: + moxitech-network: + restart: always + + + + + + + + \ No newline at end of file