fbpixel

Neste tutorial, vamos configurar a comunicação usando o protocolo UDP em um aplicativo React Native. O aplicativo React Native pode atuar como um servidor ou cliente UDP. Usamos um computador com um script Python como parceiro de comunicação.

Configurar o React Native

Primeiro, crie um projeto React Native UDPTerminalApp

Instalar as bibliotecas udp e netinfo

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
npm install react-native-udp
npm install react-native-network-info
npm install react-native-udp npm install react-native-network-info
npm install react-native-udp
npm install react-native-network-info

Descrição do código de aplicação

Importação

Para utilizar as bibliotecas, primeiro importamos o seu código.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
import dgram from 'react-native-udp'
import UdpSocket from 'react-native-udp/lib/types/UdpSocket.js';
import { NetworkInfo } from 'react-native-network-info'
import dgram from 'react-native-udp' import UdpSocket from 'react-native-udp/lib/types/UdpSocket.js'; import { NetworkInfo } from 'react-native-network-info'
   import dgram from 'react-native-udp'
   import UdpSocket from 'react-native-udp/lib/types/UdpSocket.js';
   import { NetworkInfo } from 'react-native-network-info'

Componente principal

Em seguida, criamos o componente funcional que nos permitirá gerir a comunicação do servidor

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
const UDPTerminal = () => {
const [isServer, setIsServer] = useState(false);
const [connectionStatus, setConnectionStatus] = useState('');
const [socket, setSocket] = useState<UdpSocket>();
const [ipAddress, setIpAddress] = useState('');
const [ipServer, setIpServer] = React.useState('');
const [messageText, setMessageText] = useState("");
const [messageToSend, setMessageToSend] = useState("Hello from server");
const [receivedMessage, setReceivedMessage] = useState("");
const UDPTerminal = () => { const [isServer, setIsServer] = useState(false); const [connectionStatus, setConnectionStatus] = useState(''); const [socket, setSocket] = useState<UdpSocket>(); const [ipAddress, setIpAddress] = useState(''); const [ipServer, setIpServer] = React.useState(''); const [messageText, setMessageText] = useState(""); const [messageToSend, setMessageToSend] = useState("Hello from server"); const [receivedMessage, setReceivedMessage] = useState("");
const UDPTerminal = () =>  {
  const [isServer, setIsServer] = useState(false);
  const [connectionStatus, setConnectionStatus] = useState('');
  const [socket, setSocket] = useState<UdpSocket>();
  const [ipAddress, setIpAddress] = useState('');
  const [ipServer, setIpServer] = React.useState('');
  const [messageText, setMessageText] = useState("");
  const [messageToSend, setMessageToSend] = useState("Hello from server");
  const [receivedMessage, setReceivedMessage] = useState("");
  • isServer é True se a aplicação se comportar como um servidor e false se se comportar como um cliente
  • connectionStatus apresenta o estado da ligação
  • socket contém a variável de socket para a comunicação
  • ipAddress contém o endereço IP do dispositivo Android na rede
  • ipServer contém o endereço IP introduzido na interface
  • messageText contém o texto digitado na interface
  • messageToSend contém a mensagem a enviar ao cliente ou ao servidor
  • receivedMessage contém mensagens recebidas do cliente ou do servidor

Gestão da comunicação UDP

O código utilizado para gerir a comunicação UDP, seja no modo servidor ou cliente, está inteiramente contido num hook useEffect.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
useEffect(() => {
const fetchIpAddress = async () => {
const ip = await NetworkInfo.getIPV4Address();
setIpAddress(ip);
console.log("ip adresses ; ", ip)
};
fetchIpAddress();
if (isServer) {
// Configure app as server
const server = dgram.createSocket('udp4');
server.on('message', (data, rinfo) => {
server.send(messageToSend, undefined, undefined, rinfo?.port, rinfo?.address, (error) => {
if (error) {
console.log('Error sending message:', error);
} else {
console.log('Message sent correctly');
}
});
console.log('Received message:', data.toString());
setReceivedMessage(receivedMessage => receivedMessage+data.toString()+"\n")
});
server.on('listening', () => {
console.log('Server listening on port:', server.address().port);
setConnectionStatus(`Server listening on port ${server.address().port}`);
});
try{
setReceivedMessage("");
server.bind(8888);
setSocket(server);
}catch(error){
console.log("error binding server",error);
}
} else {
setConnectionStatus(`Server disconnected`);
// Configure app as client
const client = dgram.createSocket('udp4');
try{
setReceivedMessage("");
client.bind(8887);
setSocket(client);
}catch(error){
console.log("error binding client",error);
}
}
return () => {
socket && socket.close();
};
}, [isServer, messageToSend, messageText]);
useEffect(() => { const fetchIpAddress = async () => { const ip = await NetworkInfo.getIPV4Address(); setIpAddress(ip); console.log("ip adresses ; ", ip) }; fetchIpAddress(); if (isServer) { // Configure app as server const server = dgram.createSocket('udp4'); server.on('message', (data, rinfo) => { server.send(messageToSend, undefined, undefined, rinfo?.port, rinfo?.address, (error) => { if (error) { console.log('Error sending message:', error); } else { console.log('Message sent correctly'); } }); console.log('Received message:', data.toString()); setReceivedMessage(receivedMessage => receivedMessage+data.toString()+"\n") }); server.on('listening', () => { console.log('Server listening on port:', server.address().port); setConnectionStatus(`Server listening on port ${server.address().port}`); }); try{ setReceivedMessage(""); server.bind(8888); setSocket(server); }catch(error){ console.log("error binding server",error); } } else { setConnectionStatus(`Server disconnected`); // Configure app as client const client = dgram.createSocket('udp4'); try{ setReceivedMessage(""); client.bind(8887); setSocket(client); }catch(error){ console.log("error binding client",error); } } return () => { socket && socket.close(); }; }, [isServer, messageToSend, messageText]);
  useEffect(() => {
    const fetchIpAddress = async () => {
      const ip = await NetworkInfo.getIPV4Address();
      setIpAddress(ip);
      console.log("ip adresses ; ", ip)
    };

    fetchIpAddress();

    if (isServer) {
      // Configure app as server
      const server = dgram.createSocket('udp4');

      server.on('message', (data, rinfo) => {
        
        server.send(messageToSend, undefined, undefined, rinfo?.port, rinfo?.address, (error) => {
          if (error) {
            console.log('Error sending message:', error);
          } else {
            console.log('Message sent correctly');
          }
        });
        console.log('Received message:', data.toString());
        setReceivedMessage(receivedMessage => receivedMessage+data.toString()+"\n")
      });

      server.on('listening', () => {
        console.log('Server listening on port:', server.address().port);
        setConnectionStatus(`Server listening on port ${server.address().port}`);
      });
      try{
        setReceivedMessage("");
        server.bind(8888);
        setSocket(server);
      }catch(error){
        console.log("error binding server",error);
      }
      
    } else {
      setConnectionStatus(`Server disconnected`);
      // Configure app as client
      const client = dgram.createSocket('udp4');
      try{
        setReceivedMessage("");
        client.bind(8887);
        setSocket(client);
      }catch(error){
        console.log("error binding client",error);
      }
      
    }

    return () => {
      socket && socket.close();
    };
  }, [isServer, messageToSend, messageText]);

A função fetchIpAdress é utilizada para obter o endereço IP do dispositivo.

No modo de servidor

  • criamos o socket dgram.createSocket
  • quando uma mensagem é recebida: enviamos messageToSend ao cliente
  • De seguida, apresentamos a mensagem recebida
  • ligamos o servidor à porta 8888

No modo cliente

  • criamos o socket dgram.createSocket
  • ligamos o cliente ao porto 8887

Na seguinte função

  • enviamos a mensagem messageToSend para o servidor
  • depois aguardamos a resposta, que apresentamos em receivedMessage

Função de envio de mensagens

Também definimos uma função que actualiza a mensagem enviada no modo Servidor e envia a mensagem no modo Cliente.

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
const sendMessage = () => {
setMessageToSend(messageText);
if (isServer) return;
const client = socket;
console.log("send message to "+ipServer)
client.send(messageToSend, undefined, undefined, 8888, ipServer, (error) => {
if (error) {
console.log('Error sending message:', error);
} else {
console.log('Message sent correctly');
}
});
client.on('message', async (message: { toString: () => string; }) => {
setReceivedMessage(receivedMessage+message.toString()+"\n")
});
};
const sendMessage = () => { setMessageToSend(messageText); if (isServer) return; const client = socket; console.log("send message to "+ipServer) client.send(messageToSend, undefined, undefined, 8888, ipServer, (error) => { if (error) { console.log('Error sending message:', error); } else { console.log('Message sent correctly'); } }); client.on('message', async (message: { toString: () => string; }) => { setReceivedMessage(receivedMessage+message.toString()+"\n") }); };
  const sendMessage = () => {
    setMessageToSend(messageText);
    if (isServer) return;

    const client = socket;
    console.log("send message to "+ipServer)
    client.send(messageToSend, undefined, undefined, 8888, ipServer, (error) => {
      if (error) {
        console.log('Error sending message:', error);
      } else {
        console.log('Message sent correctly');
      }
    });
    client.on('message', async (message: { toString: () => string; }) => {
      setReceivedMessage(receivedMessage+message.toString()+"\n")
    });
  };

Definição do ecrã

Por fim, a interface gráfica da aplicação é definida da seguinte forma:

  • O título da aplicação
  • O endereço IP do dispositivo
  • Um botão para selecionar o modo cliente ou servidor
  • Uma inserção para editar a mensagem a enviar
  • Um botão de envio
  • Uma inserção para especificar o endereço IP do servidor no modo de cliente
  • Uma caixa de texto para apresentar as mensagens recebidas
Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
return (
<View style={styles.mainBody}>
<Text
style={styles.mainTitle}>
AC UDP Terminal
</Text>
<ScrollView>
<View style={styles.deviceItem}>
<View>
<Text style={styles.deviceName}>{ipAddress}</Text>
<Text style={styles.deviceInfo}>{connectionStatus}</Text>
</View>
<TouchableOpacity
onPress={() => setIsServer(!isServer)}
style={styles.deviceButton}>
<Text
style={styles.buttonText}>
{isServer ? 'Server' : 'Client'}
</Text>
</TouchableOpacity>
</View>
<View
style={styles.inputBar}>
<TextInput
style={styles.textInput}
placeholder="Enter a message"
value={messageText}
onChangeText={(text) => setMessageText(text)
}
/>
<TouchableOpacity
onPress={() => sendMessage()
}
style={[styles.sendButton]}>
<Text
style={styles.buttonText}>
SEND
</Text>
</TouchableOpacity>
</View>
<TextInput
placeholder="Server IP"
onChangeText={setIpServer}
value={ipServer}
/>
<Text>Received Message:</Text>
<TextInput
editable = {false}
multiline
numberOfLines={20}
maxLength={300}
style={styles.textOutput} >
{receivedMessage}
</TextInput>
</ScrollView>
</View>
);
return ( <View style={styles.mainBody}> <Text style={styles.mainTitle}> AC UDP Terminal </Text> <ScrollView> <View style={styles.deviceItem}> <View> <Text style={styles.deviceName}>{ipAddress}</Text> <Text style={styles.deviceInfo}>{connectionStatus}</Text> </View> <TouchableOpacity onPress={() => setIsServer(!isServer)} style={styles.deviceButton}> <Text style={styles.buttonText}> {isServer ? 'Server' : 'Client'} </Text> </TouchableOpacity> </View> <View style={styles.inputBar}> <TextInput style={styles.textInput} placeholder="Enter a message" value={messageText} onChangeText={(text) => setMessageText(text) } /> <TouchableOpacity onPress={() => sendMessage() } style={[styles.sendButton]}> <Text style={styles.buttonText}> SEND </Text> </TouchableOpacity> </View> <TextInput placeholder="Server IP" onChangeText={setIpServer} value={ipServer} /> <Text>Received Message:</Text> <TextInput editable = {false} multiline numberOfLines={20} maxLength={300} style={styles.textOutput} > {receivedMessage} </TextInput> </ScrollView> </View> );
return (
    <View style={styles.mainBody}>
      <Text
        style={styles.mainTitle}>
        AC UDP Terminal
      </Text>
      <ScrollView>

      <View style={styles.deviceItem}>
                      <View>
                        <Text style={styles.deviceName}>{ipAddress}</Text>
                        <Text style={styles.deviceInfo}>{connectionStatus}</Text>
                      </View>
                      <TouchableOpacity
                        onPress={() => setIsServer(!isServer)}
                        style={styles.deviceButton}>
                        <Text
                          style={styles.buttonText}>
                          {isServer ? 'Server' : 'Client'}
                        </Text>
                      </TouchableOpacity>
                    </View>


      <View
              style={styles.inputBar}>        
              <TextInput
                style={styles.textInput}
                placeholder="Enter a message"
                value={messageText}
                onChangeText={(text) =>    setMessageText(text)
                }
              />
              <TouchableOpacity
                        onPress={() => sendMessage()
                        }
                        style={[styles.sendButton]}>
                        <Text
                          style={styles.buttonText}>
                          SEND
                        </Text>
                      </TouchableOpacity>
        </View>

      <TextInput
        placeholder="Server IP"
        onChangeText={setIpServer}
        value={ipServer}
      />
      <Text>Received Message:</Text>
              <TextInput
              editable = {false}
              multiline
              numberOfLines={20}
              maxLength={300}
              style={styles.textOutput} >
                    {receivedMessage}
              </TextInput>
      </ScrollView>
    </View>
  );

N.B.: o estilo da interface é definido na secção

Cliente UDP React-Native – Servidor UDP Python

Neste exemplo, configuramos a aplicação como um cliente e o computador como um servidor. Enviaremos uma mensagem da aplicação para o servidor, que enviará uma resposta ao cliente.

Código do servidor UDP Python

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import socket
localIP = "0.0.0.0" #"127.0.0.1"
localPort = 8888
bufferSize = 1024
msgFromServer = "Hello UDP Client"
bytesToSend = str.encode(msgFromServer)
# Create a datagram socket
UDPServerSocket = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM)
# Bind to address and ip
UDPServerSocket.bind((localIP, localPort))
print("UDP server up and listening on port {}".format(localPort))
# Listen for incoming datagrams
while(True):
data,addr = UDPServerSocket.recvfrom(bufferSize)
print("{} > {}".format(addr,data))
# Sending a reply to client
UDPServerSocket.sendto(bytesToSend, addr)
#!/usr/bin/env python # -*- coding: utf-8 -*- import socket localIP = "0.0.0.0" #"127.0.0.1" localPort = 8888 bufferSize = 1024 msgFromServer = "Hello UDP Client" bytesToSend = str.encode(msgFromServer) # Create a datagram socket UDPServerSocket = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM) # Bind to address and ip UDPServerSocket.bind((localIP, localPort)) print("UDP server up and listening on port {}".format(localPort)) # Listen for incoming datagrams while(True): data,addr = UDPServerSocket.recvfrom(bufferSize) print("{} > {}".format(addr,data)) # Sending a reply to client UDPServerSocket.sendto(bytesToSend, addr)
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import socket

localIP     = "0.0.0.0" #"127.0.0.1"
localPort   = 8888
bufferSize  = 1024

msgFromServer       = "Hello UDP Client"
bytesToSend         = str.encode(msgFromServer)

# Create a datagram socket
UDPServerSocket = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM)
 
# Bind to address and ip
UDPServerSocket.bind((localIP, localPort))
print("UDP server up and listening on port {}".format(localPort))

# Listen for incoming datagrams
while(True):

	data,addr = UDPServerSocket.recvfrom(bufferSize)
	print("{} > {}".format(addr,data))

	# Sending a reply to client
	UDPServerSocket.sendto(bytesToSend, addr)

Nota: Para escutar em todos os endereços locais, utilizamos 0.0.0.0. Se quiser testar a comunicação entre o cliente e o servidor no mesmo computador, pode utilizar o endereço 127.0.0.1.

Na aplicação, na caixa ServerIp, introduza o endereço IP do computador (aqui: 192.168.1.70). Em seguida, modifique a mensagem a enviar e prima o botão ENVIAR.

react-native-udp-client Comunicação UDP com o React Native

Terminal Python

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
UDP server up and listening on port 8888
('192.168.1.5', 8887) > b'Hello server'
('192.168.1.5', 8887) > b'Hello server'
UDP server up and listening on port 8888 ('192.168.1.5', 8887) > b'Hello server' ('192.168.1.5', 8887) > b'Hello server'
UDP server up and listening on port 8888
('192.168.1.5', 8887) > b'Hello server'
('192.168.1.5', 8887) > b'Hello server'

No terminal Python, recebemos a mensagem “Hello server” (Olá servidor) enviada pela aplicação. O servidor UDP envia de volta “Hello UDP Client” (Olá cliente UDP).

Servidor UDP React-Native – Cliente UDP Python

Aqui, configuramos a aplicação como um servidor e o computador como um cliente. No código Python, introduzimos o endereço IP do servidor.

Cliente UDP Python

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import socket
import time
HOST = "192.168.1.5" #Server IP #"127.0.0.1" local address
PORT = 8888
bufferSize = 1024
counter=0
while True:
# Create a UDP socket at client side
with socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM) as client:
# Send to server using created UDP socket
client.sendto(str.encode("client counter : "+str(counter)), (HOST,PORT))
data,addr= client.recvfrom(bufferSize)
msg = "{} > {}".format(addr,data)
print(msg)
counter+=1
time.sleep(1)
#!/usr/bin/env python # -*- coding: utf-8 -*- import socket import time HOST = "192.168.1.5" #Server IP #"127.0.0.1" local address PORT = 8888 bufferSize = 1024 counter=0 while True: # Create a UDP socket at client side with socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM) as client: # Send to server using created UDP socket client.sendto(str.encode("client counter : "+str(counter)), (HOST,PORT)) data,addr= client.recvfrom(bufferSize) msg = "{} > {}".format(addr,data) print(msg) counter+=1 time.sleep(1)
#!/usr/bin/env python
# -*- coding: utf-8 -*-
import socket
import time
HOST = "192.168.1.5" #Server IP #"127.0.0.1" local address
PORT = 8888
bufferSize = 1024

counter=0
while True:
	# Create a UDP socket at client side
	with socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM) as client:
		# Send to server using created UDP socket
		client.sendto(str.encode("client counter : "+str(counter)), (HOST,PORT))
		data,addr= client.recvfrom(bufferSize)
		msg = "{} > {}".format(addr,data)

		print(msg)
	counter+=1
	time.sleep(1)
react-native-udp-server Comunicação UDP com o React Native

Terminal Python

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
('192.168.1.5', 8888) > b'Hello client '
('192.168.1.5', 8888) > b'Hello client '
('192.168.1.5', 8888) > b'Hello client ' ('192.168.1.5', 8888) > b'Hello client '
('192.168.1.5', 8888) > b'Hello client '
('192.168.1.5', 8888) > b'Hello client '

Código completo da aplicação

App.tsx

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
/**
* npm install react-native-udp
* npm install react-native-network-info
*
*/
import React, {useState, useEffect} from 'react';
import {
View,
ScrollView,
Text,
TextInput,
PermissionsAndroid,
Platform,
TouchableOpacity } from 'react-native';
import dgram from 'react-native-udp'
import UdpSocket from 'react-native-udp/lib/types/UdpSocket.js';
import { NetworkInfo } from 'react-native-network-info'
import {styles} from "./src/styles/styles.jsx"
const UDPTerminal = () => {
const [isServer, setIsServer] = useState(false);
const [connectionStatus, setConnectionStatus] = useState('');
const [socket, setSocket] = useState<UdpSocket>();
const [ipAddress, setIpAddress] = useState('');
const [ipServer, setIpServer] = React.useState('');
const [messageText, setMessageText] = useState("");
const [messageToSend, setMessageToSend] = useState("Hello from server");
const [receivedMessage, setReceivedMessage] = useState("");
useEffect(() => {
const fetchIpAddress = async () => {
const ip = await NetworkInfo.getIPV4Address();
setIpAddress(ip);
console.log("ip adresses ; ", ip)
};
fetchIpAddress();
if (isServer) {
// Configure app as server
const server = dgram.createSocket('udp4');
server.on('message', (data, rinfo) => {
server.send(messageToSend, undefined, undefined, rinfo?.port, rinfo?.address, (error) => {
if (error) {
console.log('Error sending message:', error);
} else {
console.log('Message sent correctly');
}
});
console.log('Received message:', data.toString());
if(receivedMessage.length>300){
setReceivedMessage("");
}
setReceivedMessage(receivedMessage => receivedMessage+data.toString()+"\n")
});
server.on('listening', () => {
console.log('Server listening on port:', server.address().port);
setConnectionStatus(`Server listening on port ${server.address().port}`);
});
try{
setReceivedMessage("");
server.bind(8888);
setSocket(server);
}catch(error){
console.log("error binding server",error);
}
} else {
setConnectionStatus(`Server disconnected`);
// Configure app as client
const client = dgram.createSocket('udp4');
try{
setReceivedMessage("");
client.bind(8887);
setSocket(client);
}catch(error){
console.log("error binding client",error);
}
}
return () => {
socket && socket.close();
};
}, [isServer, messageToSend, messageText]);
const sendMessage = () => {
setMessageToSend(messageText);
if (isServer) return;
const client = socket;
console.log("send message to "+ipServer)
client.send(messageToSend, undefined, undefined, 8888, ipServer, (error) => {
if (error) {
console.log('Error sending message:', error);
} else {
console.log('Message sent correctly');
}
});
client.on('message', async (message: { toString: () => string; }) => {
if(receivedMessage.length>300){
setReceivedMessage("");
}
setReceivedMessage(receivedMessage+message.toString()+"\n")
});
};
return (
<View style={styles.mainBody}>
<Text
style={styles.mainTitle}>
AC UDP Terminal
</Text>
<ScrollView>
<View style={styles.deviceItem}>
<View>
<Text style={styles.deviceName}>{ipAddress}</Text>
<Text style={styles.deviceInfo}>{connectionStatus}</Text>
</View>
<TouchableOpacity
onPress={() => setIsServer(!isServer)}
style={styles.deviceButton}>
<Text
style={styles.buttonText}>
{isServer ? 'Server' : 'Client'}
</Text>
</TouchableOpacity>
</View>
<View
style={styles.inputBar}>
<TextInput
style={styles.textInput}
placeholder="Enter a message"
value={messageText}
onChangeText={(text) => setMessageText(text)
}
/>
<TouchableOpacity
onPress={() => sendMessage()
}
style={[styles.sendButton]}>
<Text
style={styles.buttonText}>
SEND
</Text>
</TouchableOpacity>
</View>
<TextInput
placeholder="Server IP"
onChangeText={setIpServer}
value={ipServer}
/>
<Text>Received Message:</Text>
<TextInput
editable = {false}
multiline
numberOfLines={20}
maxLength={300}
style={styles.textOutput} >
{receivedMessage}
</TextInput>
</ScrollView>
</View>
);
}
export default UDPTerminal;
/** * npm install react-native-udp * npm install react-native-network-info * */ import React, {useState, useEffect} from 'react'; import { View, ScrollView, Text, TextInput, PermissionsAndroid, Platform, TouchableOpacity } from 'react-native'; import dgram from 'react-native-udp' import UdpSocket from 'react-native-udp/lib/types/UdpSocket.js'; import { NetworkInfo } from 'react-native-network-info' import {styles} from "./src/styles/styles.jsx" const UDPTerminal = () => { const [isServer, setIsServer] = useState(false); const [connectionStatus, setConnectionStatus] = useState(''); const [socket, setSocket] = useState<UdpSocket>(); const [ipAddress, setIpAddress] = useState(''); const [ipServer, setIpServer] = React.useState(''); const [messageText, setMessageText] = useState(""); const [messageToSend, setMessageToSend] = useState("Hello from server"); const [receivedMessage, setReceivedMessage] = useState(""); useEffect(() => { const fetchIpAddress = async () => { const ip = await NetworkInfo.getIPV4Address(); setIpAddress(ip); console.log("ip adresses ; ", ip) }; fetchIpAddress(); if (isServer) { // Configure app as server const server = dgram.createSocket('udp4'); server.on('message', (data, rinfo) => { server.send(messageToSend, undefined, undefined, rinfo?.port, rinfo?.address, (error) => { if (error) { console.log('Error sending message:', error); } else { console.log('Message sent correctly'); } }); console.log('Received message:', data.toString()); if(receivedMessage.length>300){ setReceivedMessage(""); } setReceivedMessage(receivedMessage => receivedMessage+data.toString()+"\n") }); server.on('listening', () => { console.log('Server listening on port:', server.address().port); setConnectionStatus(`Server listening on port ${server.address().port}`); }); try{ setReceivedMessage(""); server.bind(8888); setSocket(server); }catch(error){ console.log("error binding server",error); } } else { setConnectionStatus(`Server disconnected`); // Configure app as client const client = dgram.createSocket('udp4'); try{ setReceivedMessage(""); client.bind(8887); setSocket(client); }catch(error){ console.log("error binding client",error); } } return () => { socket && socket.close(); }; }, [isServer, messageToSend, messageText]); const sendMessage = () => { setMessageToSend(messageText); if (isServer) return; const client = socket; console.log("send message to "+ipServer) client.send(messageToSend, undefined, undefined, 8888, ipServer, (error) => { if (error) { console.log('Error sending message:', error); } else { console.log('Message sent correctly'); } }); client.on('message', async (message: { toString: () => string; }) => { if(receivedMessage.length>300){ setReceivedMessage(""); } setReceivedMessage(receivedMessage+message.toString()+"\n") }); }; return ( <View style={styles.mainBody}> <Text style={styles.mainTitle}> AC UDP Terminal </Text> <ScrollView> <View style={styles.deviceItem}> <View> <Text style={styles.deviceName}>{ipAddress}</Text> <Text style={styles.deviceInfo}>{connectionStatus}</Text> </View> <TouchableOpacity onPress={() => setIsServer(!isServer)} style={styles.deviceButton}> <Text style={styles.buttonText}> {isServer ? 'Server' : 'Client'} </Text> </TouchableOpacity> </View> <View style={styles.inputBar}> <TextInput style={styles.textInput} placeholder="Enter a message" value={messageText} onChangeText={(text) => setMessageText(text) } /> <TouchableOpacity onPress={() => sendMessage() } style={[styles.sendButton]}> <Text style={styles.buttonText}> SEND </Text> </TouchableOpacity> </View> <TextInput placeholder="Server IP" onChangeText={setIpServer} value={ipServer} /> <Text>Received Message:</Text> <TextInput editable = {false} multiline numberOfLines={20} maxLength={300} style={styles.textOutput} > {receivedMessage} </TextInput> </ScrollView> </View> ); } export default UDPTerminal;
/**
 * npm install react-native-udp
 * npm install react-native-network-info
 * 
 */

import React, {useState, useEffect} from 'react';
import {   
  View, 
  ScrollView, 
  Text,
  TextInput,
  PermissionsAndroid,
  Platform, 
  TouchableOpacity } from 'react-native';
   import dgram from 'react-native-udp'
   import UdpSocket from 'react-native-udp/lib/types/UdpSocket.js';
   import { NetworkInfo } from 'react-native-network-info'
   import {styles} from "./src/styles/styles.jsx"


const UDPTerminal = () =>  {
  const [isServer, setIsServer] = useState(false);
  const [connectionStatus, setConnectionStatus] = useState('');
  const [socket, setSocket] = useState<UdpSocket>();
  const [ipAddress, setIpAddress] = useState('');
  const [ipServer, setIpServer] = React.useState('');
  const [messageText, setMessageText] = useState("");
  const [messageToSend, setMessageToSend] = useState("Hello from server");
  const [receivedMessage, setReceivedMessage] = useState("");

  useEffect(() => {
    const fetchIpAddress = async () => {
      const ip = await NetworkInfo.getIPV4Address();
      setIpAddress(ip);
      console.log("ip adresses ; ", ip)
    };

    fetchIpAddress();

    if (isServer) {
      // Configure app as server
      const server = dgram.createSocket('udp4');

      server.on('message', (data, rinfo) => {
        
        server.send(messageToSend, undefined, undefined, rinfo?.port, rinfo?.address, (error) => {
          if (error) {
            console.log('Error sending message:', error);
          } else {
            console.log('Message sent correctly');
          }
        });
        console.log('Received message:', data.toString());
		if(receivedMessage.length>300){
          setReceivedMessage("");
        }
        setReceivedMessage(receivedMessage => receivedMessage+data.toString()+"\n")
      });

      server.on('listening', () => {
        console.log('Server listening on port:', server.address().port);
        setConnectionStatus(`Server listening on port ${server.address().port}`);
      });
      try{
        setReceivedMessage("");
        server.bind(8888);
        setSocket(server);
      }catch(error){
        console.log("error binding server",error);
      }
      
    } else {
      setConnectionStatus(`Server disconnected`);
      // Configure app as client
      const client = dgram.createSocket('udp4');
      try{
        setReceivedMessage("");
        client.bind(8887);
        setSocket(client);
      }catch(error){
        console.log("error binding client",error);
      }
      
    }

    return () => {
      socket && socket.close();
    };
  }, [isServer, messageToSend, messageText]);

  const sendMessage = () => {
    setMessageToSend(messageText);
    if (isServer) return;

    const client = socket;
    console.log("send message to "+ipServer)
    client.send(messageToSend, undefined, undefined, 8888, ipServer, (error) => {
      if (error) {
        console.log('Error sending message:', error);
      } else {
        console.log('Message sent correctly');
      }
    });
    client.on('message', async (message: { toString: () => string; }) => {
	  if(receivedMessage.length>300){
          setReceivedMessage("");
      }
      setReceivedMessage(receivedMessage+message.toString()+"\n")
    });
  };

  return (
    <View style={styles.mainBody}>
      <Text
        style={styles.mainTitle}>
        AC UDP Terminal
      </Text>
      <ScrollView>

      <View style={styles.deviceItem}>
                      <View>
                        <Text style={styles.deviceName}>{ipAddress}</Text>
                        <Text style={styles.deviceInfo}>{connectionStatus}</Text>
                      </View>
                      <TouchableOpacity
                        onPress={() => setIsServer(!isServer)}
                        style={styles.deviceButton}>
                        <Text
                          style={styles.buttonText}>
                          {isServer ? 'Server' : 'Client'}
                        </Text>
                      </TouchableOpacity>
                    </View>


      <View
              style={styles.inputBar}>        
              <TextInput
                style={styles.textInput}
                placeholder="Enter a message"
                value={messageText}
                onChangeText={(text) =>    setMessageText(text)
                }
              />
              <TouchableOpacity
                        onPress={() => sendMessage()
                        }
                        style={[styles.sendButton]}>
                        <Text
                          style={styles.buttonText}>
                          SEND
                        </Text>
                      </TouchableOpacity>
        </View>

      <TextInput
        placeholder="Server IP"
        onChangeText={setIpServer}
        value={ipServer}
      />
      <Text>Received Message:</Text>
              <TextInput
              editable = {false}
              multiline
              numberOfLines={20}
              maxLength={300}
              style={styles.textOutput} >
                    {receivedMessage}
              </TextInput>
      </ScrollView>
    </View>
  );
}

export default UDPTerminal;

style.jsx

Plain text
Copy to clipboard
Open code in new window
EnlighterJS 3 Syntax Highlighter
/* ./src/styles/styles.jsx */
import {StyleSheet, Dimensions} from 'react-native';
/**
* links to palette
* https://colorhunt.co/palette/161616346751c84b31ecdbba
*
*/
//parameters
let BACKGROUND_COLOR = "#161616"; //191A19
let BUTTON_COLOR = "#346751"; //1E5128
let ERROR_COLOR = "#C84B31"; //4E9F3D
let TEXT_COLOR = "#ECDBBA"; //D8E9A8
const windowHeight = Dimensions.get('window').height;
export const styles = StyleSheet.create({
mainBody: {
flex: 1,
justifyContent: 'center',
height: windowHeight,
color:TEXT_COLOR,
backgroundColor: BACKGROUND_COLOR,
},
mainTitle:{
color: TEXT_COLOR,
fontSize: 30,
textAlign: 'center',
borderBottomWidth: 2,
borderBottomColor: ERROR_COLOR,
},
scanButton: {
backgroundColor: BUTTON_COLOR,
paddingBottom: 10,
paddingTop: 10,
borderRadius: 10,
margin: 2,
marginBottom: 10,
marginTop: 10,
paddingHorizontal: 20,
fontWeight: 'bold',
fontSize: 12,
},
buttonText: {
color: TEXT_COLOR,
fontWeight: 'bold',
fontSize: 12,
textAlign: 'center',
},
noDevicesText: {
color: TEXT_COLOR,
textAlign: 'center',
marginTop: 10,
fontStyle: 'italic',
},
deviceItem: {
flexDirection: 'row',
justifyContent: 'space-between',
marginBottom: 2,
},
deviceName: {
color: TEXT_COLOR,
fontSize: 14,
fontWeight: 'bold',
},
deviceInfo: {
color: TEXT_COLOR,
fontSize: 10,
},
deviceButton: {
backgroundColor: BUTTON_COLOR,
padding: 10,
borderRadius: 10,
margin: 2,
paddingHorizontal: 20,
fontWeight: 'bold',
fontSize: 12,
},
inputBar:{
flexDirection: 'row',
justifyContent: 'space-between',
margin: 5,
},
textInput:{
backgroundColor: '#888888',
margin: 2,
borderRadius: 15,
flex:3,
},
sendButton: {
backgroundColor: BUTTON_COLOR,
padding: 15,
borderRadius: 15,
margin: 2,
paddingHorizontal: 20,
},
textOutput:{
backgroundColor: '#333333',
margin: 10,
borderRadius: 2,
borderWidth: 1,
borderColor: '#EEEEEE',
textAlignVertical: 'top',
}
});
/* ./src/styles/styles.jsx */ import {StyleSheet, Dimensions} from 'react-native'; /** * links to palette * https://colorhunt.co/palette/161616346751c84b31ecdbba * */ //parameters let BACKGROUND_COLOR = "#161616"; //191A19 let BUTTON_COLOR = "#346751"; //1E5128 let ERROR_COLOR = "#C84B31"; //4E9F3D let TEXT_COLOR = "#ECDBBA"; //D8E9A8 const windowHeight = Dimensions.get('window').height; export const styles = StyleSheet.create({ mainBody: { flex: 1, justifyContent: 'center', height: windowHeight, color:TEXT_COLOR, backgroundColor: BACKGROUND_COLOR, }, mainTitle:{ color: TEXT_COLOR, fontSize: 30, textAlign: 'center', borderBottomWidth: 2, borderBottomColor: ERROR_COLOR, }, scanButton: { backgroundColor: BUTTON_COLOR, paddingBottom: 10, paddingTop: 10, borderRadius: 10, margin: 2, marginBottom: 10, marginTop: 10, paddingHorizontal: 20, fontWeight: 'bold', fontSize: 12, }, buttonText: { color: TEXT_COLOR, fontWeight: 'bold', fontSize: 12, textAlign: 'center', }, noDevicesText: { color: TEXT_COLOR, textAlign: 'center', marginTop: 10, fontStyle: 'italic', }, deviceItem: { flexDirection: 'row', justifyContent: 'space-between', marginBottom: 2, }, deviceName: { color: TEXT_COLOR, fontSize: 14, fontWeight: 'bold', }, deviceInfo: { color: TEXT_COLOR, fontSize: 10, }, deviceButton: { backgroundColor: BUTTON_COLOR, padding: 10, borderRadius: 10, margin: 2, paddingHorizontal: 20, fontWeight: 'bold', fontSize: 12, }, inputBar:{ flexDirection: 'row', justifyContent: 'space-between', margin: 5, }, textInput:{ backgroundColor: '#888888', margin: 2, borderRadius: 15, flex:3, }, sendButton: { backgroundColor: BUTTON_COLOR, padding: 15, borderRadius: 15, margin: 2, paddingHorizontal: 20, }, textOutput:{ backgroundColor: '#333333', margin: 10, borderRadius: 2, borderWidth: 1, borderColor: '#EEEEEE', textAlignVertical: 'top', } });
/* ./src/styles/styles.jsx */
import {StyleSheet, Dimensions} from 'react-native';
/**
 * links to palette
 *  https://colorhunt.co/palette/161616346751c84b31ecdbba
 * 
*/
//parameters
let BACKGROUND_COLOR = "#161616"; //191A19
let BUTTON_COLOR = "#346751"; //1E5128
let ERROR_COLOR = "#C84B31"; //4E9F3D
let TEXT_COLOR = "#ECDBBA"; //D8E9A8

const windowHeight = Dimensions.get('window').height;
export const styles = StyleSheet.create({
  mainBody: {
    flex: 1,
    justifyContent: 'center',
    height: windowHeight,
    color:TEXT_COLOR,
    backgroundColor: BACKGROUND_COLOR,
  },

  mainTitle:{
    color: TEXT_COLOR,
    fontSize: 30,
    textAlign: 'center',
    borderBottomWidth: 2,
    borderBottomColor: ERROR_COLOR,
  },

  scanButton: {
    backgroundColor: BUTTON_COLOR,
    paddingBottom: 10,
    paddingTop: 10,
    borderRadius: 10,
    margin: 2,
    marginBottom: 10,
    marginTop: 10,
    
    paddingHorizontal: 20,
    fontWeight: 'bold', 
    fontSize: 12,
  },

  buttonText: {
    color: TEXT_COLOR,
    fontWeight: 'bold',
    fontSize: 12,
	  textAlign: 'center',
  },
  
  noDevicesText: {
    color: TEXT_COLOR,
    textAlign: 'center',
    marginTop: 10,
    fontStyle: 'italic',
  },
  deviceItem: {
    flexDirection: 'row',
    justifyContent: 'space-between',
    marginBottom: 2,
  },
  deviceName: {
    color: TEXT_COLOR,
    fontSize: 14,
    fontWeight: 'bold',
  },
  deviceInfo: {
    color: TEXT_COLOR,
    fontSize: 10,
  },
  deviceButton: {
    backgroundColor: BUTTON_COLOR,
    padding: 10,
    borderRadius: 10,
    margin: 2,
    paddingHorizontal: 20,
    fontWeight: 'bold', 
    fontSize: 12,
  },

  inputBar:{
    flexDirection: 'row',
    justifyContent: 'space-between',
    margin: 5,
  },

  textInput:{
    backgroundColor: '#888888',
    margin: 2,
    borderRadius: 15,
    flex:3,
  },

  sendButton: {
  backgroundColor: BUTTON_COLOR,
  padding: 15,
  borderRadius: 15,
  margin: 2,
  paddingHorizontal: 20,
  },

  textOutput:{
    backgroundColor: '#333333',
    margin: 10,
    borderRadius: 2,
    borderWidth: 1,
    borderColor: '#EEEEEE',
    textAlignVertical: 'top',
  }

});

Aplicações

  • Controle o seu projeto Arduino, ESP32 ou Raspberry Pi com uma aplicação

Fontes