I am new to Django Channels. I am trying to replicate what is being done in this Java code using Django Channels. But I cannot figure out how to send the message JSON to the Angular frontend.
The frontend has a table that will get updated throught the websocket implementation. But the recieve method doesn't seem to replicate what the onMessage method was doing. Django Channels performs a successful handshake. But that's all that happens.
Java Code
#ServerEndpoint("/socket/order")
#ApplicationScoped
public class OrderSocket {
Set<Session> sessions = new HashSet<>();
#OnOpen
public void onOpen(Session session) {
LOG.debug("onOpen " + session.getId());
sessions.add(session);
}
#OnClose
public void onClose(Session session) {
LOG.debug("onClose " + session.getId());
sessions.remove(session);
}
#OnError
public void onError(Session session, Throwable throwable) {
LOG.debug("onError " + session.getId() + " left on error: " + throwable);
sessions.remove(session);
}
#OnMessage
public void onMessage(String message) {
LOG.debug("onMessage " + message);
broadcast(message);
}
public void broadcast(OrderDto orderDto) {
Jsonb jsonb = JsonbBuilder.create();
String jsonString = jsonb.toJson(orderDto);
broadcast(jsonString);
}
private void broadcast(String message) {
sessions.forEach(s -> {
LOG.debug("Message broadcasted: " + message);
s.getAsyncRemote().sendObject(message, result -> {
if (result.getException() != null) {
LOG.error("Unable to send message: " + result.getException());
}
});
});
}
}
Python Code
consumer.py
class OrderConsumer(WebsocketConsumer):
log = logging.getLogger('main')
def connect(self):
self.log.debug("onOpen")
self.accept()
def receive(self, text_data=None, bytes_data=None):
self.log.debug("onMessage " + text_data)
self.send(text_data="Message = " + text_data)
def disconnect(self, code):
self.log.debug("onClose")
return super().disconnect(code)
Typescript code
export class OrderWebSocketService {
private API_URL = environment.API_URL;
private SOCKET_URL = this.API_URL.replace(/http/gi, "ws");
myWebSocket: WebSocketSubject<Order> = webSocket(this.SOCKET_URL + 'socket/order/');
constructor(private snackBar: MatSnackBar) { }
public connect(): Observable<Order> {
return this.myWebSocket.asObservable().pipe(
map((obj) => obj),
catchError((error) => this.errorHandler(error))
);
}
public close(): void {
this.myWebSocket.complete();
}
errorHandler(e: any): Observable<any> {
this.showMessage('Something wrong happened with websocket!', true);
return EMPTY;
}
showMessage(msg: string, isError: boolean = false): void {
this.snackBar.open(msg, 'X', {
duration: 3000,
horizontalPosition: "right",
verticalPosition: "top",
panelClass: isError ? ['msg-error'] : ['msg-success']
});
}
}
Would appreciate any suggestions.
Step-1:
Open Visual Studio, go to File Menu, select New Project (Ctrl+Shift+N). A new window will open to create a project. Search for Windows Service (C#) from the upper right corner search box. If you do not get any Windows Service, your visual studio need to install properly (install .NET Desktop Development).
Give a service name PythonService and select OK.
Step-2:
After creating service project, User will get 04 files by default- App.config, Program.cs, ProjectInstaller.cs, Service1.cs
App.config is to configure any app data or creating connection
Program.cs will initiate the service
ProjectInstaller.cs is the installer for service. Double click on it. Click right button and add service installer. serviceInstaller1 will be added on serviceProcessInstaller1. Select property of serviceInstaller1, give a ServieName, change StartType to Automatic (if needed).
Go to serviceProcessInstaller1 property, change Account to LocalSystem
Up to this step, I provided basic service creating. Now below described the main goal.
Step-3:
Service1.cs file will consist all the necessary code for python cmd run and execute python command. Then Django server will run. The code for core python command run is-
public partial class Service1 : ServiceBase
{
private System.Timers.Timer timer = new System.Timers.Timer();
int ScheduleTime = Convert.ToInt32(ConfigurationManager.AppSettings["ThreadTime"]);
string _workingDirectory = ConfigurationManager.AppSettings["WorkingDirectory"];
string _RunServerCommand = ConfigurationManager.AppSettings["RunServerCommand"];
int sent = 0;
public Service1()
{
InitializeComponent();
}
protected override void OnStart(string[] args)
{
try
{
CommonFeature.WriteToFile("timer instantiated");
timer.Elapsed += OnElapsedTime;
timer.Interval = 5000;
timer.Enabled = true;
timer.AutoReset = false;
timer.Start();
}
catch (Exception ex)
{
CommonFeature.WriteToFile(ex.Message);
}
}
private void OnElapsedTime(object sender, ElapsedEventArgs e)
{
Execute();
}
protected override void OnStop()
{
timer.Enabled = false;
timer.Stop();
ThreadStart stop = new ThreadStart(ClosePythonInstaller);
Thread stopThread = new Thread(stop);
stopThread.Start();
Thread.Sleep(ScheduleTime * 5000);
stopThread.Abort();
}
private static void ClosePythonInstaller()
{
Process[] processList = Process.GetProcesses();
foreach (Process clsProcess in processList)
{
if (clsProcess.ProcessName == "python")
{
if (!clsProcess.HasExited)
{
clsProcess.Kill();
clsProcess.WaitForExit();
}
}
}
}
private void Execute()
{
//CommonFeature.WriteToFile(string.Format("{0}", _counter1++));
try
{
if (Process.GetProcessesByName("python").Count() == 0)
{
CommonFeature.WriteToFile("Service started");
var workingDirectory = _workingDirectory;
var runServerCommand = _RunServerCommand;
Process process = new Process();
process.StartInfo.FileName = "cmd.exe";
process.StartInfo.CreateNoWindow = true;
process.StartInfo.RedirectStandardInput = true;
process.StartInfo.RedirectStandardOutput = true;
process.StartInfo.UseShellExecute = false;
process.StartInfo.WorkingDirectory = workingDirectory;
process.Exited += new EventHandler(process_Exited);
process.Start();
CommonFeature.WriteToFile("process started");
process.StandardInput.WriteLine(runServerCommand);
process.StandardInput.Flush();
process.StandardInput.Close();
using (StreamReader reader = process.StandardOutput)
{
CommonFeature.WriteToFile("cmd command executed");
//CommonFeature.WriteToFile(string.Format("{0}", _counter2++));
string result = reader.ReadToEnd();
Console.Write(result);
}
CommonFeature.WriteToFile("script run in cmd complete");
}
}
catch (Exception)
{
throw;
}
}
protected void process_Exited(object sender, EventArgs e)
{
var p = (Process)sender;
p.WaitForExit();
sent += p.ExitCode;
}
}
This is the complete executable code for PythonService.
If there has any necessity to check the service is running or not then, user can push a message through the below class and get the final result executed or not.
public class CommonFeature
{
public static void WriteToFile(string Message)
{
string LogStatus = ConfigurationManager.AppSettings.Get("LogStatus");
if (LogStatus != null && LogStatus.ToUpper() == "ON")
{
string path = AppDomain.CurrentDomain.BaseDirectory + "\\Logs";
if (!Directory.Exists(path))
{
Directory.CreateDirectory(path);
}
string filepath = AppDomain.CurrentDomain.BaseDirectory + "\\Logs\\ServiceLog_" + DateTime.Now.Date.ToShortDateString().Replace('/', '_') + ".txt";
if (!File.Exists(filepath))
{
// Create a file to write to.
using (StreamWriter sw = File.CreateText(filepath))
{
sw.WriteLine(Message);
}
}
else
{
using (StreamWriter sw = File.AppendText(filepath))
{
sw.WriteLine(Message);
}
}
}
}
}
I am calling an api and trying to post data to it but the data is always null. The api is expeting List<KeyValuePair<string,string>>. Here is the api call and the sample code from api.
API Call (Python)
import requests
data= {'CRHandle': 'Handle',
'UpdateParam':[{'Key':'Value'},{'Key1':'Value'}]}
resp_out = requests.post("http://localhost:56011/api/values/TestData",data = data)
print(resp_out.status_code)
data_out = resp_out.text
API Method (.NET)
[HttpPost]
public string TestData([FromBody] TicketUpdateModel updateData)
{
return JsonConvert.SerializeObject(updateData);
}
Data Model
public class TicketUpdateModel
{
public string CRHandle { get; set; }
public List<KeyValuePair<string, string>> UpdateParam { get; set; }
}
Data received at API end
What am I doing wrong?
Here is a sample program I tried. See if this helps.
using System;
using System.Collections.Generic;
using System.Linq;
using Newtonsoft.Json;
public class Program
{
public static void Main()
{
var tm = new TicketUpdateModel() {
CRHandle = "blah",
UpdateParam = new List<KeyValuePair<string, string>>() {
new KeyValuePair<string, string>("Hello1", "WOrld1"),
new KeyValuePair<string, string>("Hello2", "WOrld2"),
}
};
var json = JsonConvert.SerializeObject(tm);
// prints {"CRHandle":"blah","UpdateParam":[{"Key":"Hello1","Value":"WOrld1"},{"Key":"Hello2","Value":"WOrld2"}]}
Console.WriteLine(json);
var tmd = JsonConvert.DeserializeObject<TicketUpdateModel>(json);
Console.WriteLine(tmd.CRHandle);
Console.WriteLine(tmd.UpdateParam[0].Key);
Console.WriteLine(tmd.UpdateParam[1].Value);
return;
}
}
public class TicketUpdateModel
{
public string CRHandle { get; set; }
public List<KeyValuePair<string, string>> UpdateParam { get; set; }
}
I'm using an open source library. They added a new functionality which I want but I can not upgrade the library yet.
I downloaded the relevant .py file and refrence it in my code as:
Original:
from airflow.contrib.operators.bigquery_check_operator import BigQueryCheckOperator
New:
from /home/.../airflow/MyOperators/bigquery_check_operator.py import BigQueryCheckOperator as MyBigQueryCheckOperator
However this doesn't work. it gives an invalid syntax error.
Basically I want to reference this file as MyBigQueryCheckOperator while the original one remains BigQueryCheckOperator
What am I doing wrong?
This is invalid syntax. You can't use / or file extentions in a python import path.
from /home/.../airflow/MyOperators/bigquery_check_operator.py import BigQueryCheckOperator as MyBigQueryCheckOperator
You should move the file to a relative directory and import it using regular python import syntax.
from newversion.bigquery_check_operator import BigQueryCheckOperator as MyBigQueryCheckOperator
You can add the path of the package temporarily by appending the path of the package into sys.path. Try:
import sys
sys.path.append('/home/.../airflow/MyOperators/')
from bigquery_check_operator import BigQueryCheckOperator
instead.
public class Home extends AppCompatActivity {
EditText txt_name,txt_password;
Button btn_login,btn_register;
DBHelper dbHelper;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_home);
dbHelper=new DBHelper(this);
txt_name=(EditText)findViewById(R.id.txt_name);
txt_password=(EditText)findViewById(R.id.txt_password);
btn_login=(Button) findViewById(R.id.btn_login);
btn_register=(Button) findViewById(R.id.btn_register);
}
public void buttonClick(View view){
switch (view.getId()){
case R.id.btn_login:
List<User> userList=dbHelper.readAllInfo();
int id=0;
for (int i=0;i<userList.size();i++){
User user = userList.get(i);
if(user.getUserName().equals(txt_name.getText().toString()) && user.getPassword().equals(txt_password.getText().toString())){
id=user.getId();
}
}
if(id>0){
Toast.makeText(this,"Login Successful!!!",Toast.LENGTH_SHORT).show();
Intent intent = new Intent(this,EditProfile.class);
intent.putExtra("ID",id);
startActivity(intent);
this.finish();
break;
}
else
Toast.makeText(this,"Login Unsuccessful!!!",Toast.LENGTH_SHORT).show();
break;
case R.id.btn_register:
Intent intent = new Intent(this,ProfileManagement.class);
startActivity(intent);
break;
}
}
}
public final class UserProfile {
private UserProfile(){}
public static class Users implements BaseColumns{
public final static String TABLE_NAME="UserInfo";
public final static String COLUMN_NAME="userName";
public final static String COLUMN_PASSWORD="password";
public final static String COLUMN_DOB="dateOfBirth";
public final static String COLUMN_GENDER="gender";
}
}
public class User {
private int id;
private String userName;
private String password;
private String dob;
private String gender;
public User() {
}
public User(int id, String userName, String password, String dob, String gender) {
this.id = id;
this.userName = userName;
this.password = password;
this.dob = dob;
this.gender = gender;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getDob() {
return dob;
}
public void setDob(String dob) {
this.dob = dob;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
}
public class ProfileManagement extends AppCompatActivity {
EditText txt_name,txt_password,txt_date;
RadioGroup rb_group;
RadioButton rb_male,rb_female;
Button btn_update;
DBHelper dbHelper;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_profile_management);
dbHelper=new DBHelper(this);
txt_name=(EditText)findViewById(R.id.txt_name);
txt_password=(EditText)findViewById(R.id.txt_password);
txt_date=(EditText)findViewById(R.id.txt_date);
rb_group=(RadioGroup)findViewById(R.id.rb_group);
rb_male=(RadioButton)findViewById(R.id.rb_male);
rb_female=(RadioButton)findViewById(R.id.rb_female);
btn_update=(Button) findViewById(R.id.btn_update);
}
public void PMbuttonClick(View view){
User user= new User();
user.setUserName(txt_name.getText().toString());
user.setPassword(txt_password.getText().toString());
user.setDob(txt_date.getText().toString());
if(rb_group.getCheckedRadioButtonId()==R.id.rb_male)
user.setGender("Male");
else
user.setGender("Female");
long newId=dbHelper.addInfo(user);
if(newId>0) {
Toast.makeText(this, "Successfully Added", Toast.LENGTH_SHORT).show();
Intent intent = new Intent(this,Home.class);
startActivity(intent);
finish();
}
else
Toast.makeText(this,"Unsuccessful Insertion!!!",Toast.LENGTH_SHORT).show();
}
}
public class EditProfile extends AppCompatActivity {
EditText txt_name,txt_password,txt_date;
RadioButton rb_male,rb_female;
Button btn_edit,btn_delete,btn_search;
DBHelper dbHelper;
int id;
User user;
#Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_edit_profile);
Intent intent=getIntent();
id=intent.getIntExtra("ID",-1);
dbHelper=new DBHelper(this);
user=new User();
txt_name=(EditText)findViewById(R.id.txt_name);
txt_password=(EditText)findViewById(R.id.txt_password);
txt_date=(EditText)findViewById(R.id.txt_date);
rb_male=(RadioButton)findViewById(R.id.rb_male);
rb_female=(RadioButton)findViewById(R.id.rb_female);
btn_search=(Button) findViewById(R.id.btn_search);
btn_delete=(Button) findViewById(R.id.btn_delete);
btn_edit=(Button) findViewById(R.id.btn_edit);
}
public void EPbuttonClick(View view){
switch (view.getId()){
case R.id.btn_search:
user=dbHelper.readAllInfo(id);
txt_name.setText(user.getUserName());
txt_password.setText(user.getPassword());
txt_date.setText(user.getDob());
if(user.getGender().equals("Male"))
rb_male.setChecked(true);
else
rb_female.setChecked(true);
break;
case R.id.btn_delete:
if(dbHelper.deleteInfo(id)){
Toast.makeText(this,"Successfully Deleted",Toast.LENGTH_SHORT).show();
Intent intent = new Intent(this,Home.class);
startActivity(intent);
}
break;
case R.id.btn_edit:
user.setId(id);
user.setUserName(txt_name.getText().toString());
user.setPassword(txt_password.getText().toString());
user.setDob(txt_date.getText().toString());
if(rb_male.isChecked())
user.setGender("Male");
else
user.setGender("Female");
if(dbHelper.updateInfo(user))
Toast.makeText(this,"Successfully Updated",Toast.LENGTH_SHORT).show();
else
Toast.makeText(this,"Update Unsuccessful",Toast.LENGTH_SHORT).show();
break;
}
}
#Override
public void onBackPressed() {
super.onBackPressed();
Intent intent = new Intent(this,Home.class);
startActivity(intent);
}
}
public class DBHelper extends SQLiteOpenHelper {
public static final String DATABASE="user.db";
public DBHelper(Context context) {
super(context, DATABASE, null, 1);
}
#Override
public void onCreate(SQLiteDatabase sqLiteDatabase) {
String query="CREATE TABLE "+ UserProfile.Users.TABLE_NAME +" ( "+
UserProfile.Users._ID +" INTEGER PRIMARY KEY, "+
UserProfile.Users.COLUMN_NAME +" TEXT, "+
UserProfile.Users.COLUMN_PASSWORD +" TEXT, "+
UserProfile.Users.COLUMN_DOB +" TEXT, "+
UserProfile.Users.COLUMN_GENDER +" TEXT);";
sqLiteDatabase.execSQL(query);
}
#Override
public void onUpgrade(SQLiteDatabase sqLiteDatabase, int i, int i1) {
sqLiteDatabase.execSQL("DROP TABLE IF EXISTS "+ UserProfile.Users.TABLE_NAME);
onCreate(sqLiteDatabase);
}
public long addInfo(User user){
SQLiteDatabase db=getWritableDatabase();
ContentValues values=new ContentValues();
values.put(UserProfile.Users.COLUMN_NAME,user.getUserName());
values.put(UserProfile.Users.COLUMN_PASSWORD,user.getPassword());
values.put(UserProfile.Users.COLUMN_DOB,user.getDob());
values.put(UserProfile.Users.COLUMN_GENDER,user.getGender());
long id=db.insert(UserProfile.Users.TABLE_NAME,null,values);
return id;
}
public boolean updateInfo(User user){
SQLiteDatabase db=getReadableDatabase();
ContentValues values=new ContentValues();
values.put(UserProfile.Users.COLUMN_NAME,user.getUserName());
values.put(UserProfile.Users.COLUMN_PASSWORD,user.getPassword());
values.put(UserProfile.Users.COLUMN_DOB,user.getDob());
values.put(UserProfile.Users.COLUMN_GENDER,user.getGender());
String selection= UserProfile.Users._ID+" = ?";
String[] selectionArgs={Integer.toString(user.getId())};
int count=db.update(UserProfile.Users.TABLE_NAME,values,selection,selectionArgs);
if (count>0)
return true;
else
return false;
}
public List<User> readAllInfo(){
SQLiteDatabase db=getReadableDatabase();
String[] projection={UserProfile.Users._ID,
UserProfile.Users.COLUMN_NAME,
UserProfile.Users.COLUMN_PASSWORD,
UserProfile.Users.COLUMN_DOB,
UserProfile.Users.COLUMN_GENDER};
String order= UserProfile.Users._ID+" ASC";
Cursor cursor = db.query(UserProfile.Users.TABLE_NAME,projection,null,null,null,null,order);
List<User> list = new ArrayList();
User user=new User();
while(cursor.moveToNext()){
user.setId(cursor.getInt(cursor.getColumnIndex(UserProfile.Users._ID)));
user.setUserName(cursor.getString(cursor.getColumnIndex(UserProfile.Users.COLUMN_NAME)));
user.setPassword(cursor.getString(cursor.getColumnIndex(UserProfile.Users.COLUMN_PASSWORD)));
user.setDob(cursor.getString(cursor.getColumnIndex(UserProfile.Users.COLUMN_DOB)));
user.setGender(cursor.getString(cursor.getColumnIndex(UserProfile.Users.COLUMN_GENDER)));
list.add(user);
}
return list;
}
public User readAllInfo(int id){
SQLiteDatabase db=getReadableDatabase();
String[] projection={UserProfile.Users._ID,
UserProfile.Users.COLUMN_NAME,
UserProfile.Users.COLUMN_PASSWORD,
UserProfile.Users.COLUMN_DOB,
UserProfile.Users.COLUMN_GENDER};
String selection= UserProfile.Users._ID+" = ?";
String[] selectionArgs={Integer.toString(id)};
String order= UserProfile.Users._ID+" ASC";
Cursor cursor = db.query(UserProfile.Users.TABLE_NAME,projection,selection,selectionArgs,null,null,order);
User user=new User();
while(cursor.moveToNext()){
user.setId(cursor.getInt(cursor.getColumnIndex(UserProfile.Users._ID)));
user.setUserName(cursor.getString(cursor.getColumnIndex(UserProfile.Users.COLUMN_NAME)));
user.setPassword(cursor.getString(cursor.getColumnIndex(UserProfile.Users.COLUMN_PASSWORD)));
user.setDob(cursor.getString(cursor.getColumnIndex(UserProfile.Users.COLUMN_DOB)));
user.setGender(cursor.getString(cursor.getColumnIndex(UserProfile.Users.COLUMN_GENDER)));
}
return user;
}
public boolean deleteInfo(int id){
SQLiteDatabase db=getReadableDatabase();
String selection= UserProfile.Users._ID+" = ?";
String[] selectionArgs={Integer.toString(id)};
int count=db.delete(UserProfile.Users.TABLE_NAME,selection,selectionArgs);
if(count>0)
return true;
else
return false;
}
}
public boolean deleteInfo(int id) {
SQLiteDatabase db=getReadableDatabase();
String selection= UserProfile.Users._ID+" = ?";
String[] selectionArgs={Integer.toString(id)};
int count=db.delete(UserProfile.Users.TABLE_NAME,selection,selectionArgs);
if(count>0)
return true;
else
return false;
}
I'm programming a Java client which sends an image as byte array and a Python server to receive the image. Received image height, width, channels are right,
sock = socket.socket()
sock.bind(('localhost', 8080))
sock.listen(1)
print ("Listen")
conn, addr = sock.accept()
print('Start server')
while True:
data = conn.recv(1024)
if not data:
break
img = cv2.imdecode(np.fromstring(io.BytesIO(data).getvalue(), dtype=np.uint8), 1)
np.save('snapshot.npy',img)
exit()
Showing the image using cv2.imshow('img', img) gives an incorrect result:
Java side:
public class Client implements Runnable {
private Socket socket;
private DataOutputStream out;
private String server;
private int port;
private ArrayList<ResponseListener> listeners = new ArrayList<>();
public void addListener(ResponseListener responseListener){
listeners.add(responseListener);
}
public void removeListeners(ResponseListener responseListener){
listeners.remove(responseListener);
}
Client(String server, int port) {
this.server = server;
this.port = port;
}
public void start(){
while(socket==null){
try {
socket = new Socket(server, port);
socket.setTcpNoDelay(true);
System.out.println("Ready");
listeners.forEach((listener)->listener.serverIsReady());
} catch (Exception ex) {
System.out.println("In thread " + ex.toString());
}
}
}
public void send(byte[] img) throws IOException {
out.write(img);
}
#Override
public void run() {
InputStreamReader in = null;
try {
in = new InputStreamReader(socket.getInputStream());
System.out.println(in);
out = new DataOutputStream(socket.getOutputStream());
} catch (IOException e) {
System.out.println("in or out failed");
System.exit(-1);
}
int count = 0;
while (true) {
try {
int line = in.read();
count++;
if(count==4) {
listeners.forEach((listener)->listener.onSignDefined(String.valueOf(line)));
count=0;
}
} catch (Exception e) {
System.out.println("In loop " + e.toString());
System.exit(-1);
}
}
}
}
I solved problem. Solution really easy:
data = conn.recv(640*480*3)
640*480*3 - size of image