0

So I have this java(android) code that uses DatagramPacket to send and receive udp messages.

DatagramSocket ds = null;
ds = new DatagramSocket();
            ds.setSoTimeout(30000);
            InetAddress serverAddr = InetAddress.getByName(IP_ADDRESS);
            DatagramPacket dp;
            dp = new DatagramPacket(udpMsg.getBytes(), udpMsg.length(), serverAddr, UDP_SERVER_PORT);

            ds.send(dp);

            byte[] receiveData = new byte[1024];
            DatagramPacket receivePacket = new DatagramPacket(receiveData, receiveData.length);
            ds.receive(receivePacket);
            response = new String(receivePacket.getData(), "UTF-8");

            String str = new String(receivePacket.getData(), "UTF-8");
            data1 = str.substring(0,receivePacket.getLength());


private BroadcastReceiver mMessageReceiver = new BroadcastReceiver() {

        @Override
        public void onReceive(Context context, Intent intent) {
            String sender = intent.getStringExtra("sender");
            Bundle msg = intent.getBundleExtra("message");
        }
    };

LocalBroadcastManager.getInstance(context).registerReceiver(
                mMessageReceiver, new IntentFilter("UDPBroadcast"));

Now, I want to do the same thing on iOS. I currently have this code.

let manager = SocketManager(socketURL: URL(string: "http://\(host):\(connectPort)")!, config: [.log(true), .compress])
       let socket = manager.defaultSocket

       socket.on(clientEvent: .connect) {data, ack in
           print("socket connected")
       }

       socket.on("sender") {data, ack in

           print("sender data: \(data)")
       }

       socket.connect()

But it gives me this logs

SocketIOClient{/}: Adding handler for event: connect
SocketIOClient{/}: Adding handler for event: sender
SocketIOClient{/}: Handling event: statusChange with data: [connecting]
SocketIOClient{/}: Joining namespace /
SocketManager: Tried connecting socket when engine isn't open. Connecting
SocketManager: Adding engine
SocketManager: Manager is being released
SocketIOClient{/}: Client is being released
SocketEngine: Starting engine. Server: http://255.255.255.255:6000
SocketEngine: Handshaking
SocketEnginePolling: Doing polling GET http://255.255.255.255:6000/socket.io/?transport=polling&b64=1
SocketEnginePolling: Could not connect to the server.
SocketEngine: Could not connect to the server.
SocketEngine: Engine is being released

The server I'm calling is a golang server and it's self-signed. The android code executes fast. I'm new to iOS development and sockets. If you could recommend other pods that can do socket connection other than SocketIO, please include sample code please or link to it.

UPDATE: This is my current code

import Foundation
import CocoaAsyncSocket
import SocketIO
import Starscream

class UDPSocket: NSObject, GCDAsyncUdpSocketDelegate{
    var udpSock : GCDAsyncUdpSocket!
    let listenPort: UInt16 = 6000
    let data = "test".data(using: String.Encoding.utf8)!
    let host = "255.255.255.255"
    let connectPort: UInt16 = 6000
    let manager = SocketManager(socketURL: URL(string: "http://255.255.255.255:6000")!, config: [.log(true), .compress])

    override init() {
        super.init()
        print("init")
        udpSock = GCDAsyncUdpSocket(delegate: self, delegateQueue: DispatchQueue.main)

        do{
            try udpSock!.bind(toPort: listenPort)
            try udpSock!.enableBroadcast(true)
        }catch _ as NSError {
            print("Issue with d to Port")
            return
        }

        let socket = manager.defaultSocket

        socket.on(clientEvent: .connect) {data, ack in
            print("socket connected")
        }

        socket.on("sender") {data, ack in

            print("sender data: \(data)")
        }

        socket.connect()

    }

    func sendUDP(){
        do {
            try udpSock!.beginReceiving()
            udpSock.send(data, toHost: host, port: connectPort, withTimeout: 60, tag: 0)
        }catch _ as NSError {
            print("Issue with sending to Port: ")
            return
        }
    }


    public func udpSocket(_ sock: GCDAsyncUdpSocket, didReceive data: Data, fromAddress address: Data, withFilterContext filterContext: Any?) {
        let str = NSString(data: data as Data, encoding: String.Encoding.utf8.rawValue)
        print("received: \(String(describing: str))")

        if let data1 = str?.intValue{
            if(data1 > 0){
                print("data1 isNum: \(data1)")
            }
        }

    }

    public func udpSocket(_ sock: GCDAsyncUdpSocket, didSendDataWithTag tag: Int) {

        print("didSendDataWithTag")
    }

    public func udpSocket(_ sock: GCDAsyncUdpSocket, didNotSendDataWithTag tag: Int, dueToError  error: Error?) {

        print("didNOTSendDataWithTag err: \(String(describing: error))")
    }

    public func udpSocket(_ sock: GCDAsyncUdpSocket, didNotConnect error: Error?) {
        print("didNOTConnect")
    }

    public func udpSocketDidClose(_ sock: GCDAsyncUdpSocket, withError error: Error?) {
        print("DidCloseSocket")
    }

    @objc  public func udpSocket(_ sock: GCDAsyncUdpSocket, didConnectToAddress address: Data) {
        let str = NSString(data: data as Data, encoding: String.Encoding.utf8.rawValue)
        print("didConnectToAddress addr: \(String(describing: str))")

    }
}
rminaj
  • 560
  • 6
  • 28

3 Answers3

0

It looks like your SocketManager is released due to its local scope. You should create global object of manager.

like

let manager = SocketManager(socketURL: URL(string: "http://localhost:8080")!, config: [.log(true)])
Prashant Tukadiya
  • 15,838
  • 4
  • 62
  • 98
0

Hi @rminaj this is basically what I am doing

class YourClass {

  var manager : SocketManager!
  var socket : SocketIOClient!

  func establishConnection() {
    self.manager = SocketManager(socketURL: yourUrl, config: [.log(true), .compress])
    self.socket = self.manager.defaultSocket
  }
}
sjm
  • 301
  • 2
  • 3
  • 10
  • after trying your code, the error now says `The Internet connection appears to be offline.` do you think I need to configuration something on Info.plist but I already got `App Transport Security Settings` – rminaj Oct 10 '18 at 10:19
  • Not sure. Can you access the URL somehow _outside_ the app, like `ping $url`? – sjm Oct 10 '18 at 11:21
  • I can't ping the url. But, I could call it on android – rminaj Oct 11 '18 at 01:39
0

You are using a SocketIO client. It is a library for WebSocket protocol which is over tcp.

Use SwiftSocket instead.

Its easy as

udpSocket = UDPClient(address: ADDR, port: PORT)

Or else you could use the GCDAsyncUdpSocket Reference

func setupConnection(){
    var error : NSError?
    socket = GCDAsyncUdpSocket(delegate: self, delegateQueue: dispatch_get_main_queue())
    socket.bindToPort(PORT, error: &error)
    socket.connectToHost(SERVER_IP, onPort: PORT, error: &error)
    socket.beginReceiving(&error)
    send("ping")
}

func send(message:String){
   let data = message.dataUsingEncoding(NSUTF8StringEncoding)
   socket.sendData(data, withTimeout: 2, tag: 0)
}

Possible other answers: How to implement UDP client and send data in Swift on iPhone?

MjZac
  • 3,476
  • 1
  • 17
  • 28
  • I'm already using `GCDAsyncUdpSocket` and already getting a result. But I still need to receive another data from the socket. If you look at the java code, it's the `intent.getStringExtra("sender")` – rminaj Oct 11 '18 at 03:20
  • It seems that I mixed up stuff. I think I need to use `NSNotificationCenter` to get the second value. – rminaj Oct 11 '18 at 03:56