Sometimes it crashes after 54 seconds, sometimes 56 seconds. Output looks like:
Server started. Listening for incoming connections...
55 Received message: hello server
1/12/2023 7:38:25 AM|Fatal|WebSocket.<startReceiving>b__176_2|System.ObjectDisposedException: Cannot access a disposed object.
Object name: 'System.Net.Sockets.NetworkStream'.
at System.Net.Sockets.NetworkStream.EndRead(IAsyncResult asyncResult)
at WebSocketSharp.Ext.<>c__DisplayClass48_0.<ReadBytesAsync>b__0(IAsyncResult ar)
I tried to add a try/catch block but I am not sure where the error is happening. I am running a websocketsharp server in c# and sending it sample data via python:
C# SERVER CODE:
using System;
using WebSocketSharp;
using WebSocketSharp.Server;
public class Echo : WebSocketBehavior
{
protected override void OnMessage(MessageEventArgs e)
{
try {
Console.WriteLine("Received message: " + e.Data);
Sessions.Broadcast(e.Data);
}
catch{
Console.WriteLine("bad happened");
}
}
}
public class Program
{
public static void Main(string[] args)
{
var wssv = new WebSocketServer(8081);
wssv.AddWebSocketService<Echo>("/Echo");
wssv.Start();
Console.WriteLine("Server started. Listening for incoming connections...");
Console.ReadLine();
wssv.Stop();
}
}
PYTHON CLIENT CODE:
import time
import websocket
def send_words(ws,words):
data = words
ws.send(data)
ws = websocket.create_connection("ws://localhost:8081/Echo")
while True:
time.sleep(1)
data = "hello server"
send_words(ws,data)
apparently its a websocket-sharp specific issue. You just have to add
wssv.KeepClean = false;
before
wssv.Start();
Related
I am new to angular and i want to display JSON data from python to angular with the help of node.js and I used child process to connect python and node.js but I dont know how to pass it to angular service
node.js file
const express = require('express')
const { spawn } = require('child_process')
const app = express()
const port = 8000
app.get('/', (req, res) => {
let dataToSend
let largeDataSet = []
// spawn new child process to call the python script
const python = spawn('python', ['test.py'])
// collect data from script
python.stdout.on('data', function (data) {
console.log('Pipe data from python script ...')
//dataToSend = data;
largeDataSet.push(data)
})
// in close event we are sure that stream is from child process is closed
python.on('close', (code) => {
console.log(`child process close all stdio with code ${code}`)
// send data to browser
res.send(largeDataSet.join(''))
})
})
app.listen(port, () => {
console.log(`App listening on port ${port}!`)
})
Technically you just have to send a Http GET request from your service.
I suggest that you should read and follow this offical http client guide to set it up correctly.
Here is a simple service snippet. This should be enough.
#Injectable({
providedIn: 'root',
})
export class MyService {
constructor(private http: HttpClient) {}
getData(): Observable<any> {
const url = '';
return this.http.get(url);
}
}
So I have some Swift code that send a request to my local host
//
// ContentView.swift
// Shared
//
// Created by Ulto4 on 10/23/21.
//
import SwiftUI
struct ContentView: View {
var body: some View {
VStack{
Text("Hello, world!")
.padding()
Button(action : {
self.fu()
}, label: {
Image(systemName: "pencil").resizable().aspectRatio(contentMode:.fit)
})
}
}
func fu(){
let url = URL(string: "http://127.0.0.1:5000/232")
guard let requestUrl = url else { fatalError() }
var request = URLRequest(url: requestUrl)
request.httpMethod = "GET"
let task = URLSession.shared.dataTask(with: request) { (data, response, error) in
if let error = error {
print("Error took place \(error)")
return
}
if let response = response as? HTTPURLResponse {
print("Response HTTP Status code: \(response.statusCode)")
}
}
}
struct ContentView_Previews: PreviewProvider {
static var previews: some View {
ContentView()
}
}
}
However, on my Flask app there are no get requests coming in and the function isn't running. There also isn't anything printing to the console.
I am fairly new to swift so I don't really know how to fix this.
Is there any other way to send requests in swift, if not, How would I fix this?
You are creating the URLSessionDataTask, but you never start it. Call task.resume(), e.g.
func performRequest() {
guard let url = URL(string: "http://127.0.0.1:5000/232") else {
fatalError()
}
let task = URLSession.shared.dataTask(with: url) { data, response, error in
if let error = error {
print("Error took place \(error)")
return
}
if let response = response as? HTTPURLResponse {
print("Response HTTP Status code: \(response.statusCode)")
}
}
task.resume() // you must call this to start the task
}
That having been said, a few caveats:
You are doing http rather than https. Make sure to temporarily enable insecure network requests with app transport settings, e.g.
You didn’t say if this was for macOS or iOS.
If running on physical iOS device, it will not find your macOS web server at 127.0.0.1 (i.e., it will not find a web server running on your iPhone). You will want to specify the IP number for your web server on your LAN.
If macOS, make sure to enable outbound network requests in the target’s “capabilities”:
You asked:
Is there any other way to send requests in swift?
It is probably beyond the scope of your question, but longer term, when using SwiftUI, you might consider using Combine, e.g., dataTaskPublisher. When running a simple “what was the status code” routine, the difference is immaterial, but when you get into more complicated scenarios where you have to parse and process the responses, Combine is more consistent with SwiftUI’s declarative patterns.
Let us consider a more complicated example where you need to parse JSON responses. For illustrative purposes, below I am testing with httpbin.org, which echos whatever parameters you send. And I illustrate the use of dataTaskPublisher and how it can be used with functional chaining patterns to get out of the mess of hairy imperative code:
struct SampleObject: Decodable {
let value: String
}
struct HttpBinResponse<T: Decodable>: Decodable {
let args: T
}
class RequestService: ObservableObject {
var request: AnyCancellable?
let decoder = JSONDecoder()
#Published var status: String = "Not started yet"
func startRequest() {
request = createRequest().sink { completion in
print("completed")
} receiveValue: { [weak self] object in
self?.status = "Received " + object.value
}
}
func createRequest() -> AnyPublisher<SampleObject, Error>{
var components = URLComponents(string: "https://httpbin.org/get")
components?.queryItems = [URLQueryItem(name: "value", value: "foo")]
guard let url = components?.url else {
fatalError("Unable to build URL")
}
return URLSession.shared.dataTaskPublisher(for: url)
.map(\.data)
.decode(type: HttpBinResponse<SampleObject>.self, decoder: decoder)
.map(\.args)
.receive(on: DispatchQueue.main)
.eraseToAnyPublisher()
}
}
struct ContentView: View {
#ObservedObject var requestService = RequestService()
var body: some View {
VStack{
Text("Hello, world!")
.padding()
Button {
requestService.startRequest()
} label: {
Image(systemName: "pencil").resizable().aspectRatio(contentMode:.fit)
}
Text(requestService.status)
}
}
}
But, like I said, it is beyond the scope of this question. You might want to make sure you get comfortable with SwiftUI and basic URLSession programming patterns (e.g., making sure you resume any tasks you create). Once you have that mastered, you can come back to Combine to write elegant networking code.
FWIW, like workingdog said, you could also use the new async-await rendition of data(for:delegate:). But when in the declarative world of SwiftUI, I would suggest Combine.
I have a async method which make a HttpClient call repeatedly in .Net. I simulate my code as a small console app below:
private static HttpClient req { get; set; } = new HttpClient();
static async Task Main(string[] args)
{
Console.WriteLine("Please press enter to start healthCheck");
Console.ReadLine();
healthCheck();
Console.ReadLine();
}
private static async Task healthCheck()
{
while (true)
{
req.DefaultRequestHeaders.Add("apikey", "myPassword");
string strUrl = "http://myUrl";
HttpResponseMessage hrm = await req.GetAsync(strUrl);
Console.WriteLine("=> statusCode:" + (int)hrm.StatusCode);
await Task.Delay(5000);
}
}
The output is:
The problem is when I use Postman or write this code with python as below, every time it responded 200 instead of 403.
import requests as req
import time as t
url = "http://adpsms.adpdigital.com/report/?date=2021-08-30"
customHeader = {"apikey": "sssrjdIiGisbViKA"}
i = 10
while (i > 0):
response = req.get(url, headers = customHeader)
print("statusCode: " + str(response.status_code))
i -= 1
t.sleep(5)
I supposed it is a server error but when I responded 200 every time with python I understand it would be a problem with my code or something client based.
Since my project is based on .NET I want to make it work on it.
Any suggestion would be appreciated.
On every iteration of your loop, you are adding DefaultRequestHeaders.
It means that they will be added again and again on each iteration of your cycle to the global instance of HttpClient
According to the official docs these headers will be sent with each request.
For your particular task you might add them only once(that's why the name contains prefix default.)
So if you slightly rewrite your code like this:
private static HttpClient req { get; set; } = new HttpClient();
static async Task Main(string[] args)
{
Console.WriteLine("Please press enter to start healthCheck");
Console.ReadLine();
AddDefaultHeaders();
healthCheck();
Console.ReadLine();
}
private static void AddDefaultHeaders()
{
req.DefaultRequestHeaders.Add("apiKey", "myPassword");
}
private static async Task healthCheck()
{
while (true)
{
string strUrl = "http://myUrl";
HttpResponseMessage hrm = await req.GetAsync(strUrl);
Console.WriteLine("=> statusCode:" + (int)hrm.StatusCode);
await Task.Delay(5000);
}
}
It should works fine.
I have a server written in python and an Android client written in Kotlin (in Android Studio IDE). I use sockets for maintaining this connection. After the client sends a message to the server, the server will need to send an answer to the client. I didn't find a way to receive data at the client by using sockets. I tried to do that:
var server = Socket(serverIP, serverPort)
server.outputStream.write(message.toByteArray())
var answer = server.inputStream.bufferedReader().use(BufferedReader::readText)
server.close()
but it seems not to work. If it matters, the sending at server side looks like that:
client.send(message.encode())
I suppose, you are using OkHttp for this. In my app I have the following code
private fun getClient(): OkHttpClient {
return try {
val builder = OkHttpClient.Builder()
builder.pingInterval(30, TimeUnit.SECONDS)
builder.build()
} catch (e: Exception) {
throw RuntimeException(e)
}
}
class WebSocketController(
val callback: SomeCallback
) {
private val url = "wss://your.url.com/"
private val socketClient = getClient()
private var serverSocket: WebSocket? = null
private val listener = object : WebSocketListener() {
override fun onOpen(webSocket: WebSocket, response: Response) {
super.onOpen(webSocket, response)
val json = "" // your payload to send on connect
serverSocket = webSocket
serverSocket!!.send(json)
}
override fun onMessage(webSocket: WebSocket, text: String) {
super.onMessage(webSocket, text)
val data = Json.decodeFromString<YourModel>(text)
// here you can use your data from server
callback.makeSomething(data)
}
override fun onFailure(webSocket: WebSocket, t: Throwable, response: Response?) {
super.onFailure(webSocket, t, response)
callback.onFailure(t)
}
}
fun establishConnection() {
socketClient.newWebSocket(requestBuilder().build(), listener)
}
fun disconnect() {
val json = "" // your payload on disconnect
serverSocket?.send(json)
}
private fun requestBuilder(): Request.Builder = Request.Builder().url(url)
}
I was trying to write a simple program to setup a connection between python and java using py4j. I wrote the following two lines hoping that everything would run since I'm not making any changes
from py4j.java_gateway import JavaGateway, GatewayParameters
gateway = JavaGateway(gateway_parameters=GatewayParameters(port=25335))
random = gateway.jvm.java.util.Random()
which resulted in the following error
py4j.protocol.Py4JNetworkError: An error occurred while trying to connect to the Java server (127.0.0.1:25335)
I looked around for a while and read that this might happen if java is listening on to a different port. So I wrote a for block to see what happens
for i in range(65535+1):
try:
gateway = JavaGateway(gateway_parameters=GatewayParameters(port=i))
random = gateway.jvm.java.util.Random()
print("passed port num", str(i))
except:
pass
The above block yielded nothing. None of the ports could connect. I can't figure out where I am going wrong.
How do I find the port number which the java side is using?
I am using py4j version 0.10.7 and python 3.6.0
EDIT
I have used the same java code as used in the py4j tutorial
I have a file called java_stack.java and py4j_gs.java. Both are in the same directory. I'm calling `java py4j_gs.java from the terminal. These are the contents of the two files
java_stack.java
package py4j.examples;
import py4j.GatewayServer;
public class StackEntryPoint {
private Stack stack;
public StackEntryPoint() {
stack = new Stack();
stack.push("Initial Item");
}
public Stack getStack() {
return stack;
}
public static void main(String[] args) {
GatewayServer gatewayServer = new GatewayServer(new StackEntryPoint());
gatewayServer.start();
System.out.println("Gateway Server Started");
}
}
py4j_gs.java
package py4j.examples;
import py4j.GatewayServer;
public class StackEntryPoint {
private Stack stack;
public StackEntryPoint() {
stack = new Stack();
stack.push("Initial Item");
}
public Stack getStack() {
return stack;
}
public static void main(String[] args) {
GatewayServer gatewayServer = new GatewayServer(new StackEntryPoint());
gatewayServer.start();
System.out.println("Gateway Server Started");
}
}
I also faced something same like
py4j.java_gateway:An error occurred while trying to connect to the Java server
while working on pyspark shell.
To solve this first we need to start the java geteway server.
After executing following java code my problem got resolve.
import py4j.GatewayServer;
public class Test {
public static void main(String[] args) {
Test app = new Test ();
// app is now the gateway.entry_point
GatewayServer server = new GatewayServer(app);
server.start();
}
}